浅拷贝
新对象和原对象的成员变量一致,引用变量也指向同一个对象,其中一个对象改变引用变量指向的对象内容,另一个对象中同样的变量也会跟着改变,即对于引用变量,浅拷贝复制的是其地址,并非对象本身。如下:
@Data
public class User {
private String name;
private int age;
public static void main(String[] args) {
User user = new User();
user.setName("aaa");
user.setAge(10);
User userCopy = user;
System.out.println("user :" + user.toString());
System.out.println("userCopy :" + userCopy.toString());
user.setName("bbb");
user.setAge(12);
System.out.println("user :" + user.toString());
System.out.println("userCopy :" + userCopy.toString());
}
}
//输出
// user :User(name=aaa, age=10)
// userCopy :User(name=aaa, age=10)
// user :User(name=bbb, age=12)
// userCopy :User(name=bbb, age=12)
深拷贝
新对象和旧对象的成员变量的值一致,新对象中的引用变量指向的对象也是被复制了新对象,其中一个对象改变引用变量指向的对象内容,另一个对象中同样的变量不会跟着改变,即对于引用变量,深拷贝复制的对象本身。如下:
@Data
public class User implements Cloneable{
private String name;
private int age;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User();
user.setName("aaa");
user.setAge(10);
User userCopy = (User) user.clone();
System.out.println("user :" + user.toString());
System.out.println("userCopy :" + userCopy.toString());
user.setName("bbb");
user.setAge(12);
System.out.println("user :" + user.toString());
System.out.println("userCopy :" + userCopy.toString());
}
//输出
// user :User(name=aaa, age=10)
// userCopy :User(name=aaa, age=10)
// user :User(name=bbb, age=12)
// userCopy :User(name=aaa, age=10)
}
深拷贝方式
-
被拷贝的类实现Cloneable接口,然后重写clone方法,拷贝时调用clone方法,所有引用类型的成员变量的类型都要实现Cloneable接口,然后重写clone方法。
-
Apache Commons Lang的SerializationUtils工具类。
-
json序列化、再反序列化,如:User userCopy1 = (User) JSON.parse(JSON.toJSONString(user));