共有三种对象拷贝技术:shallow copy, deep copy, lazy copy
1. shallow copy
直接将B指向A的内存地址,B原来指向的内存不再被使用。这种方法的好处是:速度快。
2. deep copy
将A中的所有数据拷贝到B中,AB不再互相依赖。缺点是有时间上的消耗(取决于数据的大小)
3. lazy copy
结合了以上两种的优点。在拷贝的初始时,做的是shallow copy,并且内部维护一个计数器,用来记录有...
Copy-on-Write
Java
There is no automatic way to copy any given object in Java.
Copying is usually performed by a clone() method of a class. This method usually, in turn, calls the clone() method of its parent class to obtain a copy, and then does any custom copying procedures. Eventually this gets to the clone() method of Object
(the uppermost class), which creates a new instance of the same class as the object and copies all the fields to the new instance (a "shallow copy")
Another way to copy objects in Java is to serialize them through the Serializable
interface. This is typically used forpersistence and wire protocol purposes, but it does create copies of objects and, unlike clone, a deep copy that gracefully handles cycled graphs of objects is readily available with minimal effort from the programmer.
利用序列化来进行deep copy确实比较简单,但是运行效率比较差。Object.clone 运行的是native代码,进行位复制,所有很快。
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
User userA = new User();
userA.setUsername("Yao Yuan");
userA.setPassword("password");
userA.setAge(32);
userA.setBirthday(new Date());
userA.setSalary(new Salary(100, 20));
User userB = (User)userA.clone();
System.out.println(userB == userA);
System.out.println(userB.equals(userA));
System.out.println(userB.getBirthday() == userB.getBirthday());
System.out.println(userB.getSalary() == userB.getSalary());
}
}
false
false
true
true
通常我们调用一个方法是为了得到 返回结果或者 改变被调用对象的状态。很少需要调用一个方法来处理它的参数;这叫作利用方法的“副作用”(Side Effect)。所以倘若创建一个会修改自己参数的方法,必须向用户明确地指出这一情况,并警告使用那个方法可能会有的后果以及它的潜在威胁。由于存在这些混淆和缺陷,所以应该尽量避免改变参数。
参考: