3

Is there anything bad or wrong about creating an interface like this and use it in a place i need to make sure a variable is cloneable?

public interface PublicCloneable<I> {
    public I clone();
}

The are questions in SO related on the fact that the Cloneable interface of java is broken and i don't understand why it isn't implemented like this.

jmacedo
  • 773
  • 1
  • 13
  • 24

3 Answers3

2

You can. The main problem with creating a new interface is that you can only use this interface on new classes that you create, which explicitly implement this interface. Existing classes in the Java library cannot implement this interface, since you can't change their code. (The interface does not magically apply to existing types.) So it's only useful if you kind of create of create a family of custom classes for all the objects you expect to use, and don't use the standard library classes.

newacct
  • 119,665
  • 29
  • 163
  • 224
1

This is fine, but you will have to provide your own cloning logic inside the method.

The idea of java.lang.Cloneable is to mark a class as cloneable and the cloning logic to be handled by the JVM. You don't provide field-by-field cloning with Object.clone()

You can pick another cloning mechanism (or use your interface in combination with another one) from the ones suggested in this answer.

Community
  • 1
  • 1
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
1

If you want to go with entirely your own implementation of clone() it should be OK. However, if you want to use Object.clone() at some point, I'd recommend

public interface PublicCloneable<I> extends Cloneable {
    public I clone();
}

and inside implementation:

   public static class MyClass implements PublicCloneable<MyClass> {
     public MyClass clone() {
        try {
            return (MyClass)super.clone(); // Or do whatever you need here
        } catch (CloneNotSupportedException e) {
            // Always supported
        }
   }

I was not sure if it compiles, but I tried and it seems ok.

Mileage can vary, of course.

Alex Gitelman
  • 24,429
  • 7
  • 52
  • 49
  • the way I learned in my poo classes was to do the clone using a copy constructor.. so it always is { return new MyClass(this) }. I never used Object.clone() and I'm not even aware of it's usefulness (does it do a deep copy automatically?). Anyway i just need the interface because I'm creating a generic class where the type parameter must have the method clone implemented, so i make sure i can use it. It is up to the user to provide a correct clone method in it's class. – jmacedo Jul 17 '11 at 21:04
  • Eurgh. `java.lang.Cloneable` is about implementation not interface. Don't mix it up with an actual interface type. – Tom Hawtin - tackline Jul 17 '11 at 22:02
  • @Tom You are entitled to your opinion but your comment in it's current form does not make much sense. – Alex Gitelman Jul 18 '11 at 00:10
  • 1
    @joxnas: The problem with copy constructors is that they don't support polymorphism. Passing a derived object to a base class's copy constructor will create a new object of the base class type, which can't support any features unique to the derived object. For example, one might have a ShapeBase class which holds a bounding rectangle, provides some methods like "translate" and "scale", and has an overridable "Draw" method which simply draws a "red X box"; other defined shape objects would override the draw method to draw things like circles, polygons, etc. – supercat Jul 18 '11 at 16:01
  • @joxnas: Even if ShapeBase supported a copy constructor, passing a Polygon to a routine that expects to copy it by calling "new ShapeBase(passedInShape);" would create BaseShape that would draw a red X in the bounding rectangle of the original polygon. One could translate, scale, etc. this new shape just as one could the original polygon, and its bounding box would shift accordingly, but one would have lost anything "polygon-ish" about it. There are two solutions: (1) Have all shape derivatives support a protected clone method which will call the native object clone method, or... – supercat Jul 18 '11 at 16:04
  • @joxnas: (2) Have every shape derivative implement its own copy constructor, and override a public cloning method to call it. I favor approach (1), since it guarantees that the new object will be of the same type as the original, and only requires derived types to override the clone method if they add fields that require something beyond a shallow copy. If one uses approach #2, every derived type must override the public clone method and implement a copy constructor, even if it doesn't add any fields, or adds fields where a shallow copy would suffice. – supercat Jul 18 '11 at 16:08