2021年02月22日java基础第二十八课----java浅拷贝和深拷贝
java基础第二十八课----java浅拷贝和深拷贝
对于java拷贝的理解
在java语言中,当我们需要拷贝一个对象的时候,常见的会有两种方式的拷贝;深拷贝和浅拷贝。
浅拷贝只是拷贝了原对象的地址,所以原对象的任何值发生改变的时候,拷贝对象的值也会随之而发生变化。
深拷贝则是拷贝了源对象的所有值而不是地址,所以即使源对象的值发上变化时,拷贝对象的值也会发生变化。
一:浅拷贝
浅拷贝示意图:
我们来做一个基本的演示:
定义一个User类
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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
定义一个测试类
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());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
输出结果:
李四
李四
-----------------------------------
asdfgh
asdfgh
- 1
- 2
- 3
- 4
- 5
当user02任何值被改变的时候,user01也会被改变。同理,user01任何值被改变时,user02也会被改变。
二:深拷贝
深拷贝意义图:
常见的几种深拷贝范式:
- 构造函数方式
- 重写clone方法
- Apache Commons Lang序列化
- Gson序列化
- Jackson序列化
①:构造函数方式
new的方式可以让每一个对象都是新创建的,他们之间互不干扰,但是new的方式在对象个数少的情况下勉强能够使用,在创建对象过多时,对系统的开销很大,所以不推荐这种方式完成。
②:重写clone()方法
1.重写Object父类继承而来的clone()方法,并修改为public
public class User implements Cloneable{
- 1
2.实现Cloneable接口来告诉我们的jvm此类允许拷贝
@Override
public User clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return (User)super.clone();
}
- 1
- 2
- 3
- 4
- 5
更改后的user
public class User implements Cloneable{
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;
}
@Override
public User clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return (User)super.clone();
}
}
更改后的Test
public static void main(String[] args) {
try {
User user01 = new User();
User user02 = user01.clone();
System.out.println(user01);
System.out.println(user02);
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
打印出来的结果
kaobei.User@15db9742
kaobei.User@6d06d69c
- 1
- 2
地址不同
但是大家注意:
1.我们新增一个类Person
public class Person {
public String name ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2.在user类当中增加
Person person = new Person();
public void ChangedPerson(String name) {
person.setName(name);
}
public String getPerson() {
return person.getName();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
最后测试类进行测试
public static void main(String[] args) {
try {
User user01 = new User();
User user02 = user01.clone();
System.out.println(user01);
System.out.println(user02);
user01.ChangedPerson("李四");
System.out.println(user01.getPerson());
System.out.println(user02.getPerson());
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
最终得出的结果是
kaobei.User@15db9742
kaobei.User@6d06d69c
李四
李四
- 1
- 2
- 3
- 4
得出结论:重写clone()方法的深拷贝方式只能对当前类进行拷贝,无法拷贝当前类引用的类:
有道云笔记更精彩哦~