Java中的clone()方法

时间:2011-06-17 11:04:41

标签: java

据我所知,方法clone()使我们能够在Java中复制对象(无参考)。但我也读到,副本很浅。那有什么意义呢? clone()方法给了我哪种能力,简单的辅助不是?

5 个答案:

答案 0 :(得分:22)

不同之处在于您可以在不修改原始对象的情况下修改克隆对象。

Point p = new Point(1,2);
Point p2 = p.clone();
Point p3 = p;
p2.x = 5;
p3.y = 7;

p3上的更改确实反馈到p,而p2上的更改却没有。{/ p>

让我们看看个别陈述后的情况如何(假设1257为对象):

Point p = new Point(1,2);

            .-----.    .-----.
 p  ----->  |  x -+--> |  1  |
            |     |    '-----'
            |     |    .-----.
            |  y -+--> |  2  |
            '-----'    '-----'


Point p2 = p.clone();

            .-----.    .-----.    .-----.
 p  ----->  |  x -+--> |  1  | <--+- x  |  <----- p2
            |     |    '-----'    |     |
            |     |    .-----.    |     |
            |  y -+--> |  2  | <--+- y  |
            '-----'    '-----'    '-----'

Point p3 = p;

            .-----.    .-----.    .-----.
 p  ----->  |  x -+--> |  1  | <--+- x  |  <----- p2
            |     |    '-----'    |     |
            |     |    .-----.    |     |
 p3 ----->  |  y -+--> |  2  | <--+- y  |
            '-----'    '-----'    '-----'


p2.x = 5;

            .-----.    .-----.    .-----.    .-----.
 p  ----->  |  x -+--> |  1  |    |  x -+--> |  5  |
            |     |    '-----'    |     |    '-----'
            |     |    .-----.    |     |
 p3 ----->  |  y -+--> |  2  | <--+- y  |  <----- p2
            '-----'    '-----'    '-----'


p3.y = 7;

            .-----.    .-----.    .-----.    .-----.
 p  ----->  |  x -+--> |  1  |    |  x -+--> |  5  |
            |     |    '-----'    |     |    '-----'
            |     |    .-----.    |     |
 p3 ----->  |  y  |    |  2  | <--+- y  |  <----- p2
            '--+--'    '-----'    '-----'
               |     .-----.
               '---> |  7  |
                     '-----'

答案 1 :(得分:7)

赋值将实例的引用复制到变量。 clone 操作将克隆该实例(并指定对该克隆的引用)。

使用分配,您最终会得到指向一个对象的多个变量,通过克隆,您将拥有多个包含多个对象引用的变量。

SomeCloneable a = new SomeCloneable();
SomeCloneable b = a;                     // a and b point to the same object

/* versus */

SomeCloneable a = new SomeCloneable();
SomeCloneable b = a.clone();             // a and b point to the different objects

答案 2 :(得分:4)

简单的赋值只会为对象创建一个Alias。使用clone(),每个属性成员也将在clone对象中初始化。但是,如果属性成员本身包含更多对象,则不会复制这些对象。

答案 3 :(得分:3)

浅拷贝是Object的默认。你可以覆盖克隆来做一个深层复制。

答案 4 :(得分:1)

要深入克隆,你必须实现Cloneable并覆盖clone()

public class MyClass implements Cloneable {

private Object attr = new Object();

@Override
public Object clone() throws CloneNotSupportedException {
    MyClass clone = (MyClass)super.clone();
    clone.attr = new Object();
    return clone;
}

@Override
public String toString() {
    return super.toString()+", attr=" + attr;
}

public static void main(String[] args) throws Exception {
    MyClass x = new MyClass();
    System.out.println("X="+x);
    MyClass y = (MyClass)x.clone();
    System.out.println("Y="+y);
}

}