前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java deep vs shallow copies

java deep vs shallow copies

作者头像
shengjk1
发布2021-03-12 11:21:53
2540
发布2021-03-12 11:21:53
举报
文章被收录于专栏:码字搬砖码字搬砖

1.背景

讨论 deep copy and shallow copy时,需要明白一点,肯定不是基本数据类型也不是 String,因为它们都是不可变的,都是值传递。换句话说,当讨论 deep copy or shallow copy时,都针对的引用类型,在讨论的是引用如何传递

2.根本区别

看引用是否指向同一个对象

shallow copy

deep copy

区别

引用指向同一个对象

引用执行不同的对象

特征

修改其中一个对象会影响另一个对象

修改其中一个对象不会影响另一个对象

3.例子

先定义 person 类,重写 hashCode 方法( 至于为什么重写 HashCode,参考 HashCode)

代码语言:javascript
复制
/**
 * @author shengjk1
 * @date 2019/9/24
 */
public class Person implements Serializable {
	private static final long serialVersionUID = 5866287941609270803L;

	private int age;
	private String name;
	private int grade;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getGrade() {
		return grade;
	}

	public void setGrade(int grade) {
		this.grade = grade;
	}

	static void run() {
		System.out.println("run....");
	}


	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		Person person = (Person) o;
		return getAge() == person.getAge() && getGrade() == person.getGrade() && Objects.equals(getName(), person.getName());
	}

	@Override
	public int hashCode() {
		return Objects.hash(getAge(), getName(), getGrade());
	}

	@Override
	public String toString() {
		return "Person{" +
				"age=" + age +
				", name='" + name + '\'' +
				", grade=" + grade +
				'}';
	}
}

主方法

代码语言:javascript
复制
HashMap<String, Person> map = new HashMap<>();
		Person person = new Person();
		person.setAge(1);
		person.setName("a");
		person.setGrade(1);

		map.put("a",person);

		System.out.println("map============");
		System.out.println("修改前 " + map.get("a"));
		person.setName("aa");
		System.out.println("修改后 " + map.get("a"));
代码语言:javascript
复制
map============
修改前 Person{age=1, name='a', grade=1}
修改后 Person{age=1, name='aa', grade=1}

命名修改的 person 中的属性,为什么map 中的person 也改变了呢?

在这里插入图片描述
在这里插入图片描述

无论是局部变量 person 还是 map 实际上都引用了同一份 Person 对象。故而当 Person 对象中的某些属性发生改变时,局部变量 person 和 map 都是可以感知到的。 那么如何才能不”相互干扰“呢,只要它们引用的对象不一致即可。

4.实现 deep copy

目前( jdk8 ) java 本身没有支持 deep copy 的实现。我们可以自己实现

  1. 重写 clone 方法,太复杂
  2. 序列化反序列化 简单 apache common lang 已经实现了
代码语言:javascript
复制
HashMap<String, Person> deelClone = SerializationUtils.clone(map);
		person.setName("b");
		System.out.println("deelClone.get(\"a\") = " + deelClone.get("a"));
		System.out.println("map.get(\"a\") = " + map.get("a"));
代码语言:javascript
复制
deelClone.get("a") = Person{age=1, name='aa', grade=1}
map.get("a") = Person{age=1, name='b', grade=1}

deep clone 之后,person name 并未发生变化

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-03-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.背景
  • 2.根本区别
  • 3.例子
  • 4.实现 deep copy
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档