About Java cloneable

I was looking for some tutorials explaining about Java Cloneable , but didn't get any good links, and Stack Overflow is becoming an increasingly obvious choice.

I would like to know the following:

  • Cloneable means that we can have a clone or copy of objects by implementing the Cloneable interface. What are the advantages and disadvantages of this?
  • How does recursive cloning happen if an object is a composite object?

Thank.

+80
java
Nov 02 '10 at 20:35
source share
6 answers

The first thing you should know about Cloneable is not to use.

It is very difficult to implement cloning with Cloneable to the right, and it's not worth it.

Instead, use some other options, such as apache-commons SerializationUtils (deep clone) or BeanUtils (shallow clone) or just use the copy constructor.

See here for Josh Bloch's views on clone using Cloneable , which explains many of the drawbacks of the approach. ( Joshua Bloch was a Sun employee and led the development of numerous Java functions.)

+132
Nov 02 '10 at 20:40
source share
— -

The cloned himself, unfortunately, is just a marker interface, that is: it does not define the clone () method.

What happens is a change in the behavior of the protected Object.clone () method, which will throw a CloneNotSupportedException for classes that do not implement Cloneable, and execute an incomplete copy of the list for classes that do.

Even if this is the behavior you are looking for, you still need to implement your own clone () method to make it public.

When implementing your own clone (), the idea is to start by creating a super.clone () object, which is guaranteed to have the correct class, and then make any additional population of fields in the case of a shallow copy is not what you want to. Calling the constructor from clone () will be problematic, as this will break inheritance if the subclass wants to add its own additional cloned logic; if he called super.clone (), in that case he would get an object of the wrong class.

This approach bypasses any logic that can be defined in your constructors, although this can be problematic.

Another problem is that any subclasses that forget to override clone () will automatically inherit the shallow copy by default, which is most likely not what you want in the event of a mutable state (which will now be split between the source and the copy) .

Most developers do not use Cloneable for these reasons and instead simply implement the copy constructor.

For more information and potential Cloneable traps, I highly recommend Joshua Bloch's book Effective Java

+34
Nov 02 '10 at 20:50
source share
  • Cloning causes an extralinguistic way of constructing objects - without constructors.
  • Cloning requires that you somehow handle a CloneNotSupportedException - or work with the client code to treat it.
  • The benefits are small - you just don't have to manually write a copy constructor.

So, use Cloneable wisely. This does not give you sufficient advantages compared to the efforts that you need to apply so that everything is correct.

+11
Nov 02 '10 at 20:45
source share

Cloning is a basic programming paradigm. The fact that Java may have implemented it weakly in many ways does not at all reduce the need for cloning. And, it's easy to implement cloning that will work, but you want it to work, shallow, deep, mixed, whatever. You can even use name cloning for a function and not use Cloneable if you want.

Suppose I have classes A, B and C, where B and C are derived from A. If I have a list of objects of type A, like this:

 ArrayList<A> list1; 

Now this list can contain objects of type A, B or C. You do not know what type of objects. Therefore, you cannot copy the list as follows:

 ArrayList<A> list2 = new ArrayList<A>(); for(A a : list1) { list2.add(new A(a)); } 

If the object does indeed have type B or C, you will not get the correct copy. And what if A is abstract? Now some people have suggested this:

 ArrayList<A> list2 = new ArrayList<A>(); for(A a : list1) { if(a instanceof A) { list2.add(new A(a)); } else if(a instanceof B) { list2.add(new B(a)); } else if(a instanceof C) { list2.add(new C(a)); } } 

This is a very, very bad idea. What if you add a new derived type? What if B or C are in another package and you do not have access to them in this class?

What you would like to do is:

 ArrayList<A> list2 = new ArrayList<A>(); for(A a : list1) { list2.add(a.clone()); } 

Many people have indicated why the underlying implementation of the Java clone is problematic. But he easily overcomes this path:

In class A:

 public A clone() { return new A(this); } 

In class B:

 @Override public B clone() { return new B(this); } 

In class C:

 @Override public C clone() { return new C(this): } 

I do not implement Cloneable, just using the same function name. If you do not like it, call it something else.

+5
Feb 15 '14 at 22:13
source share

A) There are not many advantages of cloning over copy constructor. Probably the largest of them is the ability to create a new object of the same dynamic type (provided that the declared type is cloned and has a public cloning method).

B) The clone by default creates a shallow copy and it will remain a shallow copy if your implementation of the clone does not change. This can be tricky, especially if your class has final fields

God is right, cloning can be difficult. A copy constructor / factory will satisfy most needs.

+4
Nov 02 '10 at 20:48
source share

What are the disadvantages of cloneable?

Cloning is very dangerous if the object you are copying has a composition. In this case, you need to think about a possible side effect, because the clone creates a shallow copy:

Let's say you have one object to handle db-related manipulations. Let's say this object has a Connection object as one of its properties.

So, when someone creates a clone of the originalObject , the object being created is, say, cloneObject . Here, originalObject and cloneObject keep the same reference for the Connection object.

Let's say originalObject closes the Connection object, so now cloneObject will not work because the Connection object was split between them and it was relevant closed by originalObject .

A similar problem may occur if you want to clone an object whose IOStream is a property.

How does recursive cloning happen if an object is a compound object?

Cloneable makes a shallow copy. The meaning is that the data of the source object and the clone object will point to the same link / memory. conversely, in the case of a deep copy, the data from the memory of the original object is copied to the memory of the clone object.

0
Mar 13 '16 at 5:43
source share



All Articles