克隆一个对象包含两种方式,深拷贝与浅拷贝。
浅拷贝
浅拷贝只是拷贝了原对象的地址,所以原对象的任何值发生改变的时候,拷贝对象的值也会随之而发生变化。
举一个小例子:
public class User {
private String username = "张三";
private String password = "123456";
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public static void main(String[] args) {
User user01 = new User();
User user02 = user01;
user02.setUsername("李四");
System.out.println(user01.getUsername());
System.out.println(user02.getUsername());
System.out.println("-----------------------------------");
user01.setPassword("asdfgh");
System.out.println(user01.getPassword());
System.out.println(user02.getPassword());
}
}
李四
李四
-----------------------------------
asdfgh
asdfgh
当user02任何值被改变的时候,user01也会被改变。同理,user01任何值被改变时,user02也会被改变。
深拷贝
常见的几种深拷贝范式:
- 构造函数方式
- 重写clone方法
- Apache Commons Lang序列化
- Gson序列化
- Jackson序列化
构造函数:new的方式可以让每一个对象都是新创建的,他们之间互不干扰,但是new的方式在对象个数少的情况下勉强能够使用,在创建对象过多时,对系统的开销很大,所以不推荐这种方式完成。
重写clone()方法:
1.重写Object父类继承而来的clone()方法,并修改为public
2.实现Cloneable接口来告诉我们的jvm此类允许拷贝
@Override
public User clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return (User)super.clone();
}
Object.clone()方法属于浅拷贝。如果想使用深拷贝,必须在类里面重写clone()方法。
要想调用类的clone()方法,类必须实现Cloneable接口,该接口是个空接口,如果不实现该接口,调用clone()方法会抛出异常CloneNotSupportedException。