什么是 Java 对象深拷贝?面试必问!
点击上方蓝色链接,关注并“设为星标”
介绍
拷贝对象
* 用户
*/
public class User {
private String name;
private Address address;
// constructors, getters and setters
}
/**
* 地址
*/
public class Address {
private String city;
private String country;
// constructors, getters and setters
}
方法一 构造函数
测试用例
public void constructorCopy() {
Address address = new Address("杭州", "中国");
User user = new User("大山", address);
// 调用构造函数时进行深拷贝
User copyUser = new User(user.getName(), new Address(address.getCity(), address.getCountry()));
// 修改源对象的值
user.getAddress().setCity("深圳");
// 检查两个对象的值不同
assertNotSame(user.getAddress().getCity(), copyUser.getAddress().getCity());
}
方法二 重载clone()方法
重写代码
* 地址
*/
public class Address implements Cloneable {
private String city;
private String country;
// constructors, getters and setters
@Override
public Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
}
* 用户
*/
public class User implements Cloneable {
private String name;
private Address address;
// constructors, getters and setters
@Override
public User clone() throws CloneNotSupportedException {
User user = (User) super.clone();
user.setAddress(this.address.clone());
return user;
}
}
测试用例
public void cloneCopy() throws CloneNotSupportedException {
Address address = new Address("杭州", "中国");
User user = new User("大山", address);
// 调用clone()方法进行深拷贝
User copyUser = user.clone();
// 修改源对象的值
user.getAddress().setCity("深圳");
// 检查两个对象的值不同
assertNotSame(user.getAddress().getCity(), copyUser.getAddress().getCity());
}
方法三 Apache Commons Lang序列化
重写代码
* 地址
*/
public class Address implements Serializable {
private String city;
private String country;
// constructors, getters and setters
}
* 用户
*/
public class User implements Serializable {
private String name;
private Address address;
// constructors, getters and setters
}
测试用例
public void serializableCopy() {
Address address = new Address("杭州", "中国");
User user = new User("大山", address);
// 使用Apache Commons Lang序列化进行深拷贝
User copyUser = (User) SerializationUtils.clone(user);
// 修改源对象的值
user.getAddress().setCity("深圳");
// 检查两个对象的值不同
assertNotSame(user.getAddress().getCity(), copyUser.getAddress().getCity());
}
方法四 Gson序列化
测试用例
public void gsonCopy() {
Address address = new Address("杭州", "中国");
User user = new User("大山", address);
// 使用Gson序列化进行深拷贝
Gson gson = new Gson();
User copyUser = gson.fromJson(gson.toJson(user), User.class);
// 修改源对象的值
user.getAddress().setCity("深圳");
// 检查两个对象的值不同
assertNotSame(user.getAddress().getCity(), copyUser.getAddress().getCity());
}
方法五 Jackson序列化
重写代码
* 用户
*/
public class User {
private String name;
private Address address;
// constructors, getters and setters
public User() {
}
}
* 地址
*/
public class Address {
private String city;
private String country;
// constructors, getters and setters
public Address() {
}
}
测试用例
public void jacksonCopy() throws IOException {
Address address = new Address("杭州", "中国");
User user = new User("大山", address);
// 使用Jackson序列化进行深拷贝
ObjectMapper objectMapper = new ObjectMapper();
User copyUser = objectMapper.readValue(objectMapper.writeValueAsString(user), User.class);
// 修改源对象的值
user.getAddress().setCity("深圳");
// 检查两个对象的值不同
assertNotSame(user.getAddress().getCity(), copyUser.getAddress().getCity());
}
总结
- END -
关注Java技术栈微信公众号,在后台回复关键字:Java,可以获取一份栈长整理的 Java 最新技术干货。
最近干货分享
点击「阅读原文」加入栈长的战队~
什么是 Java 对象深拷贝?面试必问!的更多相关文章
- Java面试必问之Hashmap底层实现原理(JDK1.7)
1. 前言 Hashmap可以说是Java面试必问的,一般的面试题会问: Hashmap有哪些特性? Hashmap底层实现原理(get\put\resize) Hashmap怎么解决hash冲突? ...
- 一线大厂Java面试必问的2大类Tomcat调优
一.前言 最近整理了 Tomcat 调优这块,基本上面试必问,于是就花了点时间去搜集一下 Tomcat 调优都调了些什么,先记录一下调优手段,更多详细的原理和实现以后用到时候再来补充记录,下面就来介绍 ...
- linux驱动工程面试必问知识点
linux内核原理面试必问(由易到难) 简单型 1:linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些? 2:linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化, ...
- 互联网公司面试必问的mysql题目(上)
又到了招聘的旺季,被要求准备些社招.校招的题库.(如果你是应届生,尤其是东北的某大学,绝对福利哦) 介绍:MySQL是一个关系型数据库管理系统,目前属于 Oracle 旗下产品.虽然单机性能比不上or ...
- 面试必问:JVM类加载机制详细解析
前言 在Java面试中,简历上有写JVM(Java虚拟机)相关的东西,JVM的类加载机制基本是面试必问的知识点. 类的加载和卸载 JVM是虚拟机的一种,它的指令集语言是字节码,字节码构成的文件是cla ...
- 面试必问:HashMap 底层实现原理
HashMap是在面试中经常会问的一点,很多时候我们仅仅只是知道HashMap他是允许键值对都是Null,并且是非线程安全的,如果在多线程的环境下使用,是很容易出现问题的. 这是我们通常在面试中会说的 ...
- 高级测试工程师面试必问面试基础整理——python基础(一)(首发公众号:子安之路)
现在深圳市场行情,高级测试工程师因为都需要对编程语言有较高的要求,但是大部分又没有python笔试机试题,所以面试必问python基础,这里我整理一下python基本概念,陆续收集到面试中python ...
- 互联网公司面试必问的Redis题目
Redis是一个非常火的非关系型数据库,火到什么程度呢?只要是一个互联网公司都会使用到.Redis相关的问题可以说是面试必问的,下面我从个人当面试官的经验,总结几个必须要掌握的知识点. 介绍:Redi ...
- 【面试必问】python实例方法、类方法@classmethod、静态方法@staticmethod和属性方法@property区别
[面试必问]python实例方法.类方法@classmethod.静态方法@staticmethod和属性方法@property区别 1.#类方法@classmethod,只能访问类变量,不能访问实例 ...
- TCP的分分合合(面试必问)
TCP连接与断开 目录 TCP连接与断开 前言 握手 挥手 最后 前言 相信面试过的小伙伴对这个话题应该不陌生,算是面试必问了,三次握手,四次挥手,以及其中的一些衍生问题. TCP/IP(Transm ...
随机推荐
- apply_test
//object apply_test {// def main(args:Array[String]): Unit ={// println("apply 方法:"+apply( ...
- 前端之JQuery:JQuery文档操作
jquery之文档操作 一.相关知识点总结1.CSS .css() - .css("color") -> 获取color css值 - .css("color&qu ...
- man---中英文翻译
一. 总览---SYNOPSIS 二.
- SpringCloud学习系列-Eureka服务注册与发现(4)
actuator与注册微服务信息完善 1.主机名称:服务名称修改 当前问题 含有主机名称 修改修改microservicecloud-provider-dept-8001 的yml文件 修改内容 eu ...
- git初步研究2
$git init Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令. 在执行完成 ...
- git的初步研究1
工作中很多项目再往git上迁移,所以打算研究下git git是个版本控制系统 理解git工作区.暂存区.版本库的概念 工作区:在电脑中能看到的目录 暂存区:index即索引 即首先add加入暂存区 c ...
- celery结合redis 使用
使用 Redis¶ 安装¶ 对 Redis 的支持需要额外的依赖.你可以用 celery[redis] 捆绑 同时安装 Celery 和这些依赖: $ pip install -U celery[re ...
- tomcat 启动一傘而过问题
tomcat 启动一傘而过问题 D:\apache-tomcat-7.0.75\bin startup.bat打开记事本打开 第一行:设置启动环境变量JAVA_HOME,CATALINA_HOME S ...
- Bellman-ford算法、SPFA算法求解最短路模板
Bellman-ford 算法适用于含有负权边的最短路求解,复杂度是O( VE ),其原理是依次对每条边进行松弛操作,重复这个操作E-1次后则一定得到最短路,如果还能继续松弛,则有负环.这是因为最长的 ...
- js基础补漏
1.for...in 和 for...of有何区别 for ... in循环由于历史遗留问题,它遍历的实际上是对象的属性名称.一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性. ...