• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Cloneables & Copy Constructors Allies or Enemies

 
Eric Janssens
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1608
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Eric Janssens
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1608
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I will be glad to read it. Thanks again !
[ January 23, 2006: Message edited by: John Smith ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic