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也会被改变。

二:深拷贝

深拷贝意义图:
在这里插入图片描述
常见的几种深拷贝范式:

  1. 构造函数方式
  2. 重写clone方法
  3. Apache Commons Lang序列化
  4. Gson序列化
  5. 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()方法的深拷贝方式只能对当前类进行拷贝,无法拷贝当前类引用的类:
在这里插入图片描述
有道云笔记更精彩哦~

文档:第二十七课—java浅拷贝和深拷贝.note

posted @ 2021-02-22 21:15  八佰山兵上北坡  阅读(60)  评论(0编辑  收藏  举报