Is clone() in java shallow copy?

僤鯓⒐⒋嵵緔 提交于 2019-11-30 08:58:43

The default Object.clone() is indeed a shallow copy. However, it's designed to throw a CloneNotSupportedException unless your object implements Cloneable.

And when you implement Cloneable, you should override clone() to make it do a deep copy, by calling clone() on all fields that are themselves cloneable.

It is a shallow copy because it only copies reference to other objects. Say we have these classes :

class A {
    B variable
    A() {
        variable = new B();
    }
}

class B { }

And now we make a clone of an instance of A :

A firstA = new A();
A secondA = firstA.clone();

The B instance in firstA and secondA will be the same. You won't have a copy of the B instance. This is why clone() is said to do shallow copy.

The diagrams on the page you linked should help you understand all that.

As an aside, I'm surprised nobody has mentioned Joshua Bloch's views on Cloneable

If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken. There are a few design flaws, the biggest of which is that the Cloneable interface does not have a clone method. And that means it simply doesn't work: making something Cloneable doesn't say anything about what you can do with it. Instead, it says something about what it can do internally. It says that if by calling super.clone repeatedly it ends up calling Object's clone method, this method will return a field copy of the original.

clone() creates copy of all fields. Java have primitive types and refences - when you clone your object you get a new object with copies of all primitive field (it is like deep copy) but also you have copy of all refernce fields. So in result you get two objects with they own copies of primitives and copies of references to the same objects - both original and copied object will use the same objects.

Some objects do not provide a deep copy. For example, an ArrayList will clone the list, but not the elements in the list. The following is from the JavaDoc for ArrayList:

public Object clone()

    Returns a shallow copy of this ArrayList instance. (The elements themselves are not copied.)
Dilum Ranatunga

The default implementation of Object.clone() is a shallow copy. This behavior is still useful for types that have a large number of primitive fields or Immutable fields. You can look at How to properly override clone method? for how to properly override it. After calling super.clone(), then casting the resulting object, you can then clone deeper as needed.

Implicitly, the value of clone diminishes as the number of complex, mutable fields on your type increases.

What clone does is defined for each object that chooses to support clone. Object.clone is protected, so no object allows clone unless someone has specifically defined it.

Yes.

But first you need that your class will implement Cloneable and throw exception

class A implements Cloneable{
    public int y;
    public B b;

    public A(){
        b = new B();
    }

    public static void main(String[] args) throws CloneNotSupportedException{
        A a = new A();
        A a2 = (A) a.clone();
        System.out.print(a.b==a2.b);
    }
}

Output: true

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!