I've searched around, and saw some tips, but still couldn't find the solution to my problem in hand: I need to FAITHFULLY copy an existing java object instead of creating a reference to the existing one. I don't have the access to the class, and it implements a clone method through its parent class, which actually creates a reference. I tried to go with "serialization/deserialization" route, it worked to some degrees but the copy is NOT exactly the same as the original one.
Can this be done at all?
Thanks in advance!
David
In the general case, you should not and you cannot.
Why you should not:
There are objects that should not be cloned- esp. those that reference resources outside your software's control- duplicating them could cause chaos.
Why you cannot:
Serialization and deserialization will only work if all the objects referenced by the object being cloned are serializable.
You could write some code that uses reflection to make a deep-clone by instantiating new objects and deep-cloning recursively all the fields, however, try implementing a method which can deep clone this object:
public class Evil {
public Evil() {
throw new RuntimeException();
}
}
The crux of the matter is that, if I'm not mistaken, cloning via reflection invariably depends on invoking constructors via Reflection, and constructors are not guaranteed to work.
However, in most cases, this approach will clone most objects. But you still should not do that! I can't think of a valid scenario for doing this.
edit: also, as some commenters pointed out "faithful copy" is quite ill-defined.
edit 2: conclusion: only a class can know if it should be cloneable and how to do it.
Try the Java deep cloning library
Cloner cloner = new Cloner();
cloner.deepClone(object);
Related
I have the interface of an object. I don't know if the implementation is serializable or not. Nor Cloneable.
And I don't have getters of object properties, actually, I don't know the properties either.
Can I still clone the object?
I mean, can I do something like:
public void copyMyObject(MyObject myObject){
this.copyOfMyObject = ...//? can I make a deep copy?
}
I guess not...but maybe I am missing something.
Well ... it depends.
You can serialize an object if the object's actual class implements Serializable ... and the rest1. The actual type may be different to the (static) type of the variable where you are getting the object's reference from.
But if not, then you are not missing something. Deep copying an object that doesn't implement its own deep copy methods, getters and setters, or some form of serialization, would involve some extremely nasty coding2.
You are better off designing your classes so that they can be serialized / cloned. Or, so that you don't need to clone them.
Note that there are a few Java classes that would be impossible to clone correctly even by "nasty" means. Examples include Thread, Socket, Class, ClassLoader and some key awt classes. So if your (hypothetical) application design depended on (say) being able to clone a running thread, that design would not be implementable.
1 - Instance fields that are not transient and not null need to be serializable as well. And so on.
2 - For example, you could conceivably make use of abstraction breaking reflection and use of the Unsafe to replicate what the object serialization implementation does under the hood ... without the Serializable type check. It is a bad idea though.
I was going through the "special" features of Java, and started reading up on Cloning.
So currently what I understand is Cloning can be used to get a identical copy of an object. To do this you implement the Cloneable interface and override the clone method of Object(Which is really weird IMO)
My questions is more towards the comparison between C++ and Java. Why exactly is a separate clone method required when we already have support for copy constructors. Was there a historical reason on why cloning was thought of as must have feature?
PS: I am not asking about the need to "clone" as in what is the need of cloning a object in Java, what I am asking is the need for Cloneable and the clone method, when Java already supports copy constructors.
IMO you question has two parts.
What is the need for the Cloneable interface?
The Cloneable interface is also known as a marker interface, which means that it does not have any methods, its whole purpose is to tell you, the user of that class, that it implements the clone() method which is inherited from Object. This enables you to do a check before calling the clone() method:
Animal a = new Dog();
Animal b;
if (a instanceof Cloneable)
b = a.clone();
This happens pretty often in Java; see for example the Serializable interface.
Why does Java need a clone() method at all, as it already has copy constructors?
The very short answer is polymorphism. How would you correctly clone a Dog instance, through a reference to an Animal, its super class, if you didn't have the clone() method?
Clone is meant to provide a a separate instance of an object without destroying the cloned one. It's quite useful(it's a must) in prototype pattern.
Copy constructor is usually called in C++ when passing by value (you can do use it at construction time as well, but usually it's called when passing objects through the stack either as paremeters or returns). So often times the initial object gets out of scope.
You can eventually interchange these two if you really want to go at it, but in reality they serve different purposes, and having clarity when one should be used instead of another is very helpful.
Besides the disambiguation of the name, you need to think about polymorphism , where you want to clone the object from a base pointer.
Copy constructors will be called on the type of pointer, while clone (if virtual, like it should be) will be called on the most derived implementation.
This question already has answers here:
clone() vs copy constructor vs factory method?
(10 answers)
Closed 8 years ago.
clone method vs copy constructor in java. which one is correct solution. where to use each case?
Clone is broken, so dont use it.
THE CLONE METHOD of the Object class
is a somewhat magical method that does
what no pure Java method could ever
do: It produces an identical copy of
its object. It has been present in the
primordial Object superclass since the
Beta-release days of the Java
compiler*; and it, like all ancient
magic, requires the appropriate
incantation to prevent the spell from
unexpectedly backfiring
Prefer a method that copies the object
Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}
Read more
http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx
Have in mind that clone() doesn't work out of the box. You will have to implement Cloneable and override the clone() method making in public.
There are a few alternatives, which are preferable (since the clone() method has lots of design issues, as stated in other answers), and the copy-constructor would require manual work:
BeanUtils.cloneBean(original) creates a shallow clone, like the one created by Object.clone(). (this class is from commons-beanutils)
SerializationUtils.clone(original) creates a deep clone. (i.e. the whole properties graph is cloned, not only the first level) (from commons-lang), but all classes must implement Serializable
Java Deep Cloning Library offers deep cloning without the need to implement Serializable
clone() was designed with several mistakes (see this question), so it's best to avoid it.
From Effective Java 2nd Edition, Item 11: Override clone judiciously
Given all of the problems associated with Cloneable, it’s safe to say
that other interfaces should not extend it, and that classes
designed for inheritance (Item 17) should not implement it. Because of
its many shortcomings, some expert programmers simply choose never to
override the clone method and never to invoke it except, perhaps, to
copy arrays. If you design a class for inheritance, be aware that if
you choose not to provide a well-behaved protected clone method, it
will be impossible for subclasses to implement Cloneable.
This book also describes the many advantages copy constructors have over Cloneable/clone.
They don't rely on a risk-prone extralinguistic object creation mechanism
They don't demand unenforceable adherence to thinly documented conventions
They don't conflict with the proper use of final fields
They don't throw unnecessary checked exceptions
They don't require casts.
All standard collections have copy constructors. Use them.
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
Keep in mind that the copy constructor limits the class type to that of the copy constructor. Consider the example:
// Need to clone person, which is type Person
Person clone = new Person(person);
This doesn't work if person could be a subclass of Person (or if Person is an interface). This is the whole point of clone, is that it can can clone the proper type dynamically at runtime (assuming clone is properly implemented).
Person clone = (Person)person.clone();
or
Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer
Now person can be any type of Person assuming that clone is properly implemented.
See also: How to properly override clone method?. Cloning is broken in Java, it's so hard to get it right, and even when it does it doesn't really offer much, so it's not really worth the hassle.
Great sadness: neither Cloneable/clone nor a constructor are great solutions: I DON'T WANT TO KNOW THE IMPLEMENTING CLASS!!! (e.g. - I have a Map, which I want copied, using the same hidden MumbleMap implementation) I just want to make a copy, if doing so is supported. But, alas, Cloneable doesn't have the clone method on it, so there is nothing to which you can safely type-cast on which to invoke clone().
Whatever the best "copy object" library out there is, Oracle should make it a standard component of the next Java release (unless it already is, hidden somewhere).
Of course, if more of the library (e.g. - Collections) were immutable, this "copy" task would just go away. But then we would start designing Java programs with things like "class invariants" rather than the verdammt "bean" pattern (make a broken object and mutate until good [enough]).
Clone does not call the object constructor to create a copy of the object. So what algorithm does clone use ?
I am looking for implementation details of the native method clone. Any pointers will be appreciated.
Note that I am aware of the shortcomings of clone.
protected native Object clone(). I don't know exactly (I need to take a look at the native code) but it makes a new instance of the object inside the JVM and copies all fields.
But you should avoid using clone() - it is hard to get it right. Look at this question for more details
How it works is laid out in the Javadoc:
The method clone for class Object performs a specific cloning operation. First, if the class of this object does not implement the interface Cloneable, then a CloneNotSupportedException is thrown. Note that all arrays are considered to implement the interface Cloneable. Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.
E.g., a naive, shallow field-by-field copy, very nearly (but probably not quite) just a bit-for-bit copy of the object.
I am looking for implementation details of the native method clone.
That will vary from JVM implementation to JVM implementation. It's likely to be quite an efficient operation, though, if that's your concern.
In terms of JNI, clone is (or could be) implemented using the AllocObject method which creates a new object without invoking any constructor (as opposed to NewObject). When you have the new object, reflection is used to shallowly copy all fields.
But then again, the clone/Clonable mechanism is fundamentally broken in Java. Joshua Bloch has a section about it in Effective Java. There is also several related SO questions about it.
The Object.clone() implementation is a native method that checks that the object's class implements Cloneable, and then simply allocates a new instance and does a field-by-field shallow copy. The copying is most likely done using a memory copy - there's no need for it to do anything more fancy. (But if you really want to know, look at the OpenJDK source code.)
I have never seen clone() method put to use in any real code. I was reading about it and felt that its use could make the code very cumbersome.
is there any specific use case for the clone() method? Under what circumstances would one have to use clone() and why would the use of normal conctructor not suffice?
clone is very convenient to make defensive copies of arrays passed to methods or constructors (as all array types are Cloneable, and the signature for clone()is covariant so that boolean[].clone() actually returns a boolean[] rather than an Object). That's the only really good use I've seen of it in ten years, though...
Josh Bloch in Effective Java also doesn't recommend to use clone () method.
There are several problems with this method:
If cloneable object has not only primitive type fields but also object fields, then cloned object will receive just references to those objects but not real cloned objects. To avoid this all inner objects should be cloneable too.
If you make a subclass of cloneable class, then it's cloneable too (even if you don't want). That's why you should override clone() method in a proper way to avoid possible problems.
When you should use it: never if possible. You should use it very carefully. If all fields in object you want to make cloneable are of primitive type then it's not dangerous. In all other cases think twice before using it.