aspose file tools*
The moose likes Java in General and the fly likes Cloneables & Copy Constructors      Allies or Enemies Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Cloneables & Copy Constructors      Allies or Enemies" Watch "Cloneables & Copy Constructors      Allies or Enemies" New topic
Author

Cloneables & Copy Constructors Allies or Enemies

Eric Janssens
Ranch Hand

Joined: Sep 26, 2005
Posts: 53
During the reading of one of the technical articles of Sun ( Article on Cloning and Serialization )

I found this:





If you uncomment the line that attempts to set final field "c", the program won't compile. So instead of using clone to set the field, the program uses a copy constructor. A copy constructor is a constructor for the class that takes an object reference of the same class type, and implements the appropriate copying logic.


As a cloning can be done by "Cloneable - clone()" or by "Copy constructor" (by obligation due to some limitation). Is it better to let both as access for the outside or is it better to "encapsulate" the copy constructor in the clone() method so that only the clone() method and Cloneable interface are seen by the outside.

Some points:
* the Cloneable definition is actually tightly couple with Object.clone()
* 2 differents access to do the same thing
* the actual usage
* some possible hidden side effect
etc.

So, which one is better? both as access for an object cloning or only the clone() method
And why?
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
This is a very interesting question - one that no doubt will have a multitude of answers from a multitude of people with varying levels of understanding. Let's make one thing clear - the notion of 'newness' is itself not intrinsic to requirements, since a client of an object/contract implementation has never cared about 'newness'. What they have cared about, in some circumstances, is the identity of a contract implementation - and specifically, when the contract exposes the ability to 'mutate'. Specifying "newness" (or equivalent) in a requirement specification is called a requirement defect (a more general term for excess of requirements). That is, since requirements have been exceeded, the specification contains a requirement defect.

There is a very subtle difference between "newness" and "contract implementation identity". Sidestepping that issue for a moment, I refer anyone to the ContractualJ API Specification which explicitly states: "All constructors are declared private, and throw java.lang.UnsupportedOperationException, unless they are implicit constructors of anonymous classes. Exposing construction details (as Java constructor semantics implies) is not permitted."

This is because constructors (as we known them) implicitly exceed requirements, and the language (thankfully) provides a more appropriate (but still not optimal) alternative.

The definition of 'mutate' needs to be stated: "When invocation of one operation on the contract can be observed through invocation of some other operation". Here is an example:
interface I{void setX(int x); int getX();}
You will note that invocation of the setX operation can have an effect that is observed through the getX operation. Therefore, you would care about identity of contract implementation (implementation of interface I) since the contract exposes mutating operations - since of course, after you invoke setX, you wish to know the identity of the contract implementation through which you can observe a side effect.

This also leads to another interesting issue: the setX operation is not symbiotic with the getX operation - the relationship is unidirectional (symbiosis demands bidirectional relationship). That is, the setX operation is directly related to, and dependent on for its existence, the getX operation, but the getX operation can exist in a legitimate use case on its own (without the setX) operation. We often express this relationship using interface inheritance, but this has devstating consequences, albeit being the best known option within the language. A new language may consider offering a more appropriate expression of this requirement.

On this premise, which I have understated quite extensively (for now), it is quite clear that "cloning" or "copy constructors" really have no legitimate existence within a valid requirement specification More so, the identity of a contract implementation is what is paramount. If cloning and/or copy constructors are what does it for you, then so be it, however, I offer the possibility that a more appropriate alternative exists. The downfall being the mandate of a third party dependency which mandates some kind of expression of "newness". That is to say, you are forced to care about something you shouldn't by some dependency. I run into this issue myself quite regularly, and even within the Java language itself. It is important to acknowledge these dependent requirement defects if indeed that is what you have, so that you can make a fully informed decision about the pros and cons of your available options.

In summary, both Cloneable and/or copy constructors are equally (infinitely) invalid, however, you may be able to exceed and/or produce invalid requirements without clients ever knowing about it. The whole industry rides on this premise - from my perspective at least (I can't speak for the *entire* industry, but I'm waiting for a scrap of evidence to the contrary).

I hope this little rant helps - mainly, that you understand that the answer to your question is really quite non-trivial (despite the extreme simplifications that you will no doubt receive), and is probably best answered by Thinking for Yourself as is any reality that is obscured by the popular belief system. Good luck mate.


Tony Morris
Java Q&A (FAQ, Trivia)
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by John Smith:

As a cloning can be done by "Cloneable - clone()" or by "Copy constructor" (by obligation due to some limitation). Is it better to let both as access for the outside or is it better to "encapsulate" the copy constructor in the clone() method so that only the clone() method and Cloneable interface are seen by the outside.


I'm not sure I understand your question. In the example, the copy constructor and the clone method actually work independently from each other, and do different things. If you want to provide both versions as a service to the outside, both need a public API, obviously.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Eric Janssens
Ranch Hand

Joined: Sep 26, 2005
Posts: 53
Thank you both for your replies.

Originally posted by Ilja Preuss:

I'm not sure I understand your question. In the example, the copy constructor and the clone method actually work independently from each other, and do different things. If you want to provide both versions as a service to the outside, both need a public API, obviously.


I don’t see why I would like to have both as public API. The example is just here to demonstrate a problem you can encounter with clone() + Cloneable.

They both try to make the same thing and should have the same result << tell me if I am wrong here (but the conventional clone() method can encounter some issue)

They are dependent of each other’s. Using a copy constructor at any point of a class hierarchy will have repercussions (the "copy constructor" class will not properly implement the possible Cloneable interfaces of the upper classes and the independency of the cloning in all the hierarchy is lost)


To Tony Morris:
Nice post but you are flying far too high for my little brain
I don’t count anymore the number of times I have read your post!

I hope this little rant helps - mainly, that you understand that the answer to your question is really quite non-trivial

After your post I don’t doubt that anymore

I can link `newness` in many aspect of my problem. ( Cloneable definition, usage, etc. ) But I am not sure it is really what you mean.

I completely fail to link the 'mutate' concept (from your definition) even if I am aware that both have dependencies.

I offer the possibility that a more appropriate alternative exists. The downfall being the mandate of a third party dependency which mandates some kind of expression of "newness"
Did you have an alternative?

Again, thank you for your reply. I create this topic to have different ideas of how people have resolve this issue but perhaps it s not a so frequent problem.

nice to see how people think about it anyway.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by John Smith:
Did you have an alternative?


At the moment, I am refactoring my web site - one objective is to have publications written using a DocBook source (as opposed to XHTML as it currently stands). After this, I plan to write an article to address your issue that is more complete and perhaps easier to understand i.e. I will use layperson speak and review it carefully.

Sorry for confusing you. Ignore what I say for now.
Eric Janssens
Ranch Hand

Joined: Sep 26, 2005
Posts: 53
I will be glad to read it. Thanks again !
[ January 23, 2006: Message edited by: John Smith ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Cloneables & Copy Constructors Allies or Enemies