3

I am in the process of migrating to java from c++ and consider myself a java noob. I have been looking recently at a vast code base with several examples of the kind public class Myclass implements Cloneable{...} with no implementation of the clone function. I fail to understand the advantages of this pattern. Are there any? If you choose not to implement the clone function, why derive it from Cloneable? Also are there any lombok anotations which provide some default clone functions?

cplusplusrat
  • 1,435
  • 12
  • 27
  • `Cloneable` is an example of what is called a [marker interface](https://en.wikipedia.org/wiki/Marker_interface_pattern). Today, it would perhaps be marked using an annotation, but those didn't exist in Java then. – Jiri Tousek Dec 07 '16 at 21:02
  • `Cloneable` is an old marker interface. The correct and very simple answer is simply 'don't use it'. Nobody does. See http://www.artima.com/intv/bloch13.html For good, easy to digest answers to such questions and to help you with your migration, get and leaf through _Effective Java_. – pvg Dec 07 '16 at 21:29

3 Answers3

1

If a class does not implement the Cloneable interface, calling clone on an instance of the class results in a CloneNotSupportedException. The java.lang.Object already implements a clone method (this method is not abstract), so subclasses are not required to implement it. The clone method of java.lang.Object performs a shallow copy of the instance.

M A
  • 71,713
  • 13
  • 134
  • 174
  • 1
    But isn't the clone method protected in the object class. That should automatically prevent any consumers of `MyClass` from calling the clone function. – cplusplusrat Dec 07 '16 at 20:50
  • 1
    Right, but since it is protected, subclasses can invoke it in their implementation. If other classes need to call it, it can be overriden and made `public`. – M A Dec 07 '16 at 20:55
  • 1
    Ok, so the point of implementing a `Cloneable` interface without providing an actual implementation is to avoid the subclasses from calling the `clone` function from the base Object class? – cplusplusrat Dec 07 '16 at 20:59
  • The only point of implementing Cloneable is to allow cloning an instance of the implementing class. As the docs say, "By convention, classes that implement this interface should override Object.clone (which is protected) with a public method". One possibility is that the method is being invoke using reflection or some other dynamic fashion. – M A Dec 07 '16 at 21:31
  • There is really no point to implementing `Cloneable`. It's an old design (way back from Java 1.0) that unfortunately did not pan out and is now well understood to be essentially broken. There is some insight to be gained from discussing the details of its operation but as a practical matter, it's important to point out that the correct answer is "don't use `Cloneable`" – pvg Dec 07 '16 at 21:40
1

If you choose not to implement the clone function, why derive it from Cloneable?

The clone() method doesn't derive from the Cloneable interface.
It comes from the Object class.
Cloneable is simply a marker interface.
It is used at runtime to valid the behavior if the clone() method is called on a instance of a class.
Java has chosen a design model where by default the object owns the clone() method. It is a design choice you may like or not but anyway, it is like that
Concretely, if you call clone() on a object and the class of the object doesn't implement Clonable, the JVM will at runtime throw a CloneNotSupportedException exception. In a same way, some classes throw UnsupportedOperationException if one of their method is not implemented.

Also are there any lombok anotations which provide some default clone functions?

By default, clone() performs a shallow copy of the current object. That is, a new instance is created for the object you are cloning but all object fields that it owns are not cloned. Indeed, the fields of the cloned object still reference the same objects than those in the original instance. Only fields with primitive types (int, float, boolean, etc...) are cloned.
If you need to have a different behavior in the clone() method, Lombok cannot guess what is the behavior you want to have. So, no it makes no sense to use it to generate the implementation of the clone() method.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • "Concretely, if you call clone() on a object and the class of the object doesn't implement Clonable, the JVM will at runtime throw a CloneNotSupportedException exception." Only if the object's `clone()` method somehow uses `Object.clone()`. If the class implements `clone()` in a way that doesn't use `Object.clone()`, then whether `Cloneable` is implemented or not makes no difference. – newacct Dec 09 '16 at 02:48
0

There is actually a @Wither annotation in lombok: https://projectlombok.org/features/experimental/Wither.html

But you could also just create a new object passing parameters to a constructor.

HectorBarbossa
  • 185
  • 1
  • 3
  • 9
  • "But you could also just create a new object passing parameters to a constructor." That won't automatically create the right class of object for subclasses. – newacct Dec 09 '16 at 02:49
  • the annotation is deprecated now and replaced by @With. But when u use the With annotation it creates new instance after each with... calling, so there will be more performance if you would use usual constructor – Zhenyria Mar 24 '23 at 08:28