I am studying Java because I need it as a prerequirement in one of my college courses. I come from a C++ background, so understanding the logic underlying OOP is not particularly difficult. But there are several differences between the two languages, and one I just cannot figure out is the object cloning feature present in Java. The problem recalls me that of the copy constructor for C++, but the implications are just different.
In Java, there are no destructors and memory is managed by a garbage collector, so there are not the heap memory issues you face in C++. The problem is limited to sharing variables.
Now, reading around, I found that object cloning (unlike copy constructors) is not a feature that an OOP language should provide, as it creates another instance of an object skipping the construction phase. Moreover, clone() cannot manipulate final fields properly, and skip initialization blocks. The same logic behind clonation is "wrong" because "Cloneable" is just like an empty interface, provided only to make a type check in Object.clone(), to raise an exception if the type of the object is not Cloneable.
All the cloning mechanism seems to rely on the Object.clone() method, which allocates memory properly. Each subtype in the class hierarchy supporting clone(), should make a call to "super.clone()" until the Object one is called to allocate all necessary fields. But what happens if a subtype, implementing the Cloneable interface, extends a supertype not doing so? I'm studying from "Arnold, Gosling, Holmes", and one of the defined behaviours towards clone is: "Allow subclasses to support clone but don't publicly support it. Such a class doesn't implement Cloneable, but if the default implementation of clone isn't correct, the class provides a protected clone implementation that clones its fields correctly". This way, calling super.clone(), in the end we will bump into the protected clone() method of the superclass, but such method cannot rely on Object.clone(), because the superclass itself doesn't implement Cloneable. Using the new operator would be an error, because an instance of the superclass would be created, with some missing fields.
So, is supporting clone() (with a protected method) in a non-Cloneable class really useful? And how can one solve the problem of a Cloneable subtype with non-Cloneable supertype?