The Source for Java Technology Collaboration
User: Password:



Andreas Schaefer

Andreas Schaefer's Blog

Proposal to fix the Cloneable Problem

Posted by schaefa on October 13, 2004 at 09:02 AM | Comments (10)

I know that probably backward compatibility is the main reason to keep java.lang.Cloneable as it is. Nevertheless as I hopefully showed in my rant about this still unresolved issue this shortcoming of the Cloneable interface is still haunting us. To prevent the impression that I only complain about problems I am going to suggest a solution to this problem that, I hope, will end this problem once and for all.

I would suggest the following addition to the JDK (Please adjust the name of the interface as you like I just could not think of a better one):

package java.lang;

public interface XCloneable
	extends Cloneable {
   // The exception still can be thrown if a reference is not cloneable
   public Object clone()
      throw CloneNotSupportedException;
}
Now all the classes in the JDK that implements Cloneable and provide a public clone() method could now extend XCloneable and we all could life happily ever after.

This should fix the shortcoming of Cloneable and still is backward compatible. It is just ugly to add another interface but, I guess, that is the price for backward compatibility.

Let's go Tiger - Andy

Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Naming suggestions: java.lang.PubliclyCloneable java.util.Cloneable While we're fixing the interface, how about defining some annotation, so that the user knows what kind of clone is being returned?
    JSR 250: Common Annotations for the Java Platform

    Posted by: coxcu on October 13, 2004 at 10:58 AM

  • Their backwards-compatibility excuse is rubbish. Breaking applications that implemented Clonable but did not provide clone() is not a problem. I keep on repeating this: application that do this broke the design contract of Clonable and as such we are allowed to (and should) break them! This is a source-level compatibility change. As Sun has pointed out, binary-compatibility is unaffected. Lets just change Clonable instead of extending it and be done with it. Just my 2 cents...

    Posted by: cowwoc on October 14, 2004 at 07:52 AM

  • While normally I would just say 'break them all and let Bob sort it out', if we can create something called ReallyCloneable and still maintain backwards compatibility I think that is preferable. I always thought it was stupid to have a Clonable without a clone() method myself... what its cloneable but there is no explicit way to clone it? Now that is just silly.

    Posted by: gregorypierce on October 14, 2004 at 09:20 AM

  • There is also another problem with "clone()":

    it does not return the correct type. This could have been changed in java 1.5 because covariant return types are now supported, but backward compatibility forbids the change

    (see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5096552).

    To solve all problems we need an interface like this:

    public interface PublicCloneable extends Cloneable { public Object getClone(); }

    With this interface we get:

    - a public methot that returns a clone

    - we can be sure that we can clone an object that implements it

    - classes that extend it can return the correct type (it is new so no existing class cah have extendid it with return type "Object")

    Whether "getClone" should throw "CloneNotSupportedException" is debateable, I guess not.

    Posted by: bmandl on October 14, 2004 at 10:47 AM

  • public interface PublicClonable<X extends PublicClonable<X>> extends Clonable {
        X getClone();
    }
    
    // normal use case
    class Widget implements PublicClonable<Widget> {
        public Widget getClone() { ... }
    }
    
    // and if you're at the nurture end of the nature / nurture debate -
    // and no this is not a copy paste problem, the clone is
    // a different type to the parent/donor
    class MyWidget implements PublicClonable<Widget> {
        public Widget getClone() { ... }
    }
    

    Posted by: brucechapman on October 14, 2004 at 06:58 PM

  • Thanks for working this out, this is exacty how I think is should be done.

    Could you add this also to my RFE http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5096552

    The typical implementeation will look like this:

    // normal use case
    class Widget implements PublicCloneable {
      public Widget getClone() { 
        try {
          return (Widget)super.clone();
        }
        catch(CloneNotSupportedException e) {
          return null;
        }
      }
    }
    
    If all Cloneable classes in the JDK would also implement PublicCloneable we could finally forget that there is something like cast (at least almost)

    Posted by: bmandl on October 15, 2004 at 08:00 AM

  • Thanks to 'bmandl' great suggestion. I think this is the way to go. Maybe with the exception of catching the CNSException making debugging of inner, not cloneable components quit difficult, I think.
    -Andy

    Posted by: schaefa on October 16, 2004 at 11:04 AM

  • The definitive discussion of Cloneable is in "Effective Java". Since that's not available on-line, here's a link to a conversation with "Effective Java" author, Josh Bloch, about copy constructors versus cloning.

    Posted by: coxcu on March 24, 2005 at 02:41 PM

  • good article and goood example "we cannot clone a person"

    Posted by: completeajay on June 14, 2007 at 04:39 AM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds