目录
这里说的拷贝主要是针对引用类型,而对于基本数据类型,拷贝就是直接把值给另一个对象
1.浅拷贝(只拷贝原对象的地址)
-
原对象的值发生变化,拷贝对象的值也会随之发生变化,因为原对象和拷贝对象是同一块空间
-
// 实体类 public class User { private String name = "张三"; private String password = "123456"; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", password='" + password + '\'' + '}'; } } // 测试类 class Test { public static void main(String[] args) { // 浅拷贝 User user1 = new User(); System.out.println(user1); User user2 = user1; System.out.println(user2); System.out.println("密码改变前:"); System.out.println(user1.getPassword()); System.out.println(user2.getPassword()); user1.setPassword("123"); System.out.println("密码改变后:"); System.out.println(user1.getPassword()); System.out.println(user2.getPassword()); } }
2.深拷贝(拷贝原对象的所有值)
-
原对象的值发生变化,拷贝对象的值不发生变化,因为原对象与拷贝对象是两份不同的空间
-
// 测试类 class Test { public static void main(String[] args) { // 深拷贝 User user1 = new User(); user1.setName("李四"); user1.setPassword("666"); User user2 = new User(); user2.setName(user1.getName()); user2.setPassword(user1.getPassword()); System.out.println(user1); System.out.println(user2); System.out.println("密码改变前:"); System.out.println(user1.getPassword()); System.out.println(user2.getPassword()); user1.setPassword("123"); System.out.println("密码改变后:"); System.out.println(user1.getPassword()); System.out.println(user2.getPassword()); } }
上面的代码就是构造器方式进行深拷贝,发现,是把user1中的每个属性都赋值给user2的属性,这种方法固然可以,但是太过于繁琐
-
深拷贝的方式
-
构造器方式(对象少量时可以使用此方法;要拷贝大量对象时,因为要不停的new对象,开销比较大,所以不推荐)
-
重写clone方法方式
-
实现Cloneable接口,目的是为了告诉jvm本类允许被拷贝
-
重写Object中的clone方法,修改clone方法的访问修饰符,由protected改成public
-
public class User implements Cloneable { private String name = "张三"; private String password = "123456"; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", password='" + password + '\'' + '}'; } @Override public User clone() throws CloneNotSupportedException { return (User) super.clone(); } }
-
public class Test { public static void main(String[] args) throws CloneNotSupportedException { // 浅拷贝 // clone方法实现 User user1 = new User(); user1.setName("李四"); User user2 = user1.clone(); System.out.println("密码改变前:"); System.out.println(user1); System.out.println(user2); user1.setPassword("123"); System.out.println("密码改变后:"); System.out.println(user1); System.out.println(user2); } }
但是默认的clone只能拷贝一层的对象,对于超过一层的对象,只能进行浅拷贝,例如下面的代码,是两层的拷贝,在第二层的person类型的拷贝中,只是进行了浅拷贝
-
class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class User implements Cloneable { private String name = "张三"; private String password = "123456"; private Person person = new Person(); public String getName() { return name; } public void changePersonName(String name) { person.setName(name); } public String getPersonName() { return person.getName(); } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", password='" + password + '\'' + ", person=" + person + '}'; } @Override public User clone() throws CloneNotSupportedException { return (User) super.clone(); } }
-
public class Test { public static void main(String[] args) throws CloneNotSupportedException { User user1 = new User(); User user2 = user1.clone(); System.out.println("修改内部引用类型属性前:"); System.out.println(user1); System.out.println(user2); user1.changePersonName("wangwu"); user1.setName("zhangsan"); System.out.println("修改内部引用类型属性后:"); System.out.println(user1); System.out.println(user2); } }
-
-
Apache Common Lang序列化
-
Gson序列化
-
JackSon序列化
-