据我所知,方法clone()
使我们能够在Java中复制对象(无参考)。但我也读到,副本很浅。那有什么意义呢? clone()
方法给了我哪种能力,简单的辅助不是?
答案 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>
让我们看看个别陈述后的情况如何(假设1
,2
,5
,7
为对象):
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);
}
}