Path: csiph.com!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Robert Klemme Newsgroups: comp.lang.java.programmer Subject: Re: Are you sure, Mr. Gosling? Date: Tue, 7 Jun 2016 23:25:49 +0200 Lines: 75 Message-ID: References: <1eb77568-ae31-4316-ac21-a33db79c5aa4@googlegroups.com> <5c864ac4-9634-4c88-9d6b-d14dbf3b3886@googlegroups.com> <746532a2-c6db-4d58-afc0-1cc57440eff5@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net zqNyoNx9rgNFkw4JHAtOQANeoC+aZk7CZaTb6mnc311tUhnGI= Cancel-Lock: sha1:i9WOjqT9Tyc92b9ak/z+hQtgJrY= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 In-Reply-To: Xref: csiph.com comp.lang.java.programmer:34548 On 07.06.2016 23:12, Eric Sosman wrote: > On 6/7/2016 1:22 PM, Eric Douglas wrote: >> On Tuesday, June 7, 2016 at 1:10:36 PM UTC-4, Robert Klemme wrote: >>> That sounds more like a use case for clone() to me as it seems to stress >>> that the original type is preserved. It really depends on the usage. >> >> Maybe I'm getting confused then. I thought clone() sounded wrong >> because it should return an instance of that class, so if you extend >> the class and call super.clone it gets an instance of the base class? >> If your extended class needs to return an instance of itself, which >> needs to copy all the same values as the super class plus a few more... The usual implementation invokes super.clone() exactly as Eric has shown in this posting. And Object.clone() makes sure the type of the instance is the same as the receiver of the method. > The clone() calls will percolate all the way up to Object's clone(), > which will check that the originating object implements Cloneable and > them return a field-for-field copy of that originating object, with the > originating object's class. (In this instance the intervening clone() > calls just pass that object along, so the class of the eventual object > is BaseClass or ExtendedClass, depending on where things started.) > > But if one or more of obj{1,2,3} is unshareable, the clone() methods > must provide suitable substitutes: clones or copies of the unshareable > objects. Let's suppose the odd-numbered fields must be unique; then > you'd have something like > > public class BaseClass implements Cloneable { > // ... > @Override > public Object clone() throws CloneNotsupportedException { > BaseClass cloned = (BaseClass) super.clone(); > cloned.obj1 = independentCopyOf(obj1); > // obj2 can be shared; just leave it alone. > return cloned; > } > // ... > } > > public class ExtendedClass extends BaseClass { > // ... > @Override > public Object clone() throws CloneNotsupportedException { > ExtendedClass cloned = (ExtendedClass) super.clone(); > cloned.obj3 = independentCopyOf(obj3); > return cloned; > } > // ... > } One note though: I would catch CloneNotsupportedException in the BaseClass implementation of clone() because the exception cannot be thrown. It just pollutes the signature of clone() unnecessarily. > Finally, the clone() methods I've shown simply pass along the > object created by Object's clone(), whose class will be the same as > that of the ultimate "leaf" class of the clone operation. That's a > fairly normal state of affairs, but it is *not* enforced, nor even > required. It is entirely possible (though perverse) that the clone() > method applied to a Woozle object might instead return a Grizzle, > or even a String. Or even null. You have to know what to expect > from the chain of superclasses. Any reasonable implementation would _not_ deviate from the convention to propagate clone() calls in the way you have shown. Doing that opens the box of Pandora _and_ the Gates of Hell (and I am not talking about Bill). Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/