对象copy的两种方式--序列化--clone
对象实现copy有多中方式,最土的方法就是直接new,然后塞值,不过这种方法是真的low,下面着重说说Object类中的clone() 和 序列化反序列化copy
Object 中 clone的方法
1.Object中clone 方法是protected,虽然所有类都继承自object 但是在不同包下调用还是不被允许的,因此要重写clone方法。
2.调用clone方法clone对象时要求对象实现Cloneable接口,否则会抛出 CloneNotSupportedException
/** @return a clone of this instance.
* @throws CloneNotSupportedException if the object's class does not
* support the {@code Cloneable} interface. Subclasses
* that override the {@code clone} method can also
* throw this exception to indicate that an instance cannot
* be cloned.
* @see java.lang.Cloneable
*/
protected native Object clone() throws CloneNotSupportedException;
clone 方法可以实现对象的浅copy ,什么是浅copy 举个例子
人 有 头 和 名字 两个属性 , 头 又有 头发 属性 ,现在使用clone方法 克隆一个人,则clone出来的人和原有的人是两个对象,但是发现两个人的头在内存中只有一个,也就是说,clone出来的人使用了原有人的头对象。如果改了其中一个对象头对象的属性,另一个也会跟着变。
序列化和反序列化,将对象读到内存中,在从内存中读取出来
需要对象实现 Serializable 接口
直接上代码了,自己跑即可:
import lombok.extern.slf4j.Slf4j; import java.io.*; /**
* @ClassName CommonUtils
* @Description <工具类></>
* @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
* @Date 2018/12/4 11:39
* @Version 1.0
*/
@Slf4j
public class CommonUtils { /**
* @return T
* @Description <深度克隆对象,对象需要序列化>
* @Author Zhaiyt
* @Date 14:11 2018/12/4
* @Param [obj]
**/
public static <T extends Serializable> T clone(T obj) {
try {
//将对象读取到内存中
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(obj);
//从内存中读取
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (T) objectInputStream.readObject();
} catch (IOException e) {
log.error("clone Object IOException");
} catch (ClassNotFoundException e) {
log.error("clone Object ClassNotFoundException");
}
return null;
} public static void main(String[] args) {
Person p = new Person();
p.setName("zhangsan");
p.setSix("男");
Head h = new Head();
h.setHair("black");
p.setHead(h);
Person cloneP = clone(p);
System.out.println("深copy对象的属性 p.head 和 cloneP.head 是否相等");
System.out.println(p.getHead().equals(cloneP.getHead())); //浅copy
Person clone;
try {
clone = (Person) p.clone();
System.out.println("浅copy对象的属性 p.head 和 clone.head");
System.out.println(p.getHead().equals(clone.getHead()));
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
} /**
* @ClassName <Person>
* @Description <人对象>
* @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
* @Date 2018/12/4 16:12
* @Version 1.0
*/
class Person implements Serializable, Cloneable {
private String name; private String six; private Head head; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSix() {
return six;
} public void setSix(String six) {
this.six = six;
} public Head getHead() {
return head;
} public void setHead(Head head) {
this.head = head;
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
} @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", six='" + six + '\'' +
", head=" + head +
'}';
}
} /**
* @ClassName <Head>
* @Description <人的属性>
* @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
* @Date 2018/12/4 16:11
* @Version 1.0
*/
class Head implements Serializable {
private String hair; public String getHair() {
return hair;
} public void setHair(String hair) {
this.hair = hair;
} @Override
public String toString() {
return "Head{" +
"hair='" + hair + '\'' +
'}';
}
}
序列化和反序列化后出来的对象发现属性对象不再是同一个对象了。
对象copy的两种方式--序列化--clone的更多相关文章
- Java中对象拷贝的两种方式
引用的拷贝 //引用拷贝 private static void copyReferenceObject(){ Person p = new Person(23, "zhang") ...
- 检测对象类型的两种方式,constructor属性和instanceof
//本例是为了记录检测对象类型的两种方式,即constructor属性和instanceof操作符.详见<高三>P145 function Person(name, age, ...
- Redis:存储对象的两种方式(序列化和json字符串)
方式一:序列化操作 public class SerializeUtil { /* * 序列化 * */ public static byte[] serizlize(Object ...
- JVM中对象访问定位两种方式
1.通过句柄方式访问, 在Java堆中分出一块内存进行存储句柄池,这样的话,在栈中存储的是句柄的地址 优点: 当对象移动的时候(垃圾回收的时候移动很普遍),这样值需要改变句柄中的指针,但是栈中的指针不 ...
- java 的对象拷贝(有深浅拷贝两种方式,深拷贝实现的两种方式(逐层实现cloneable接口,序列化的方式来实现))
Java提高篇--对象克隆(复制)(转自:http://www.cnblogs.com/Qian123/p/5710533.html#_label0) 阅读目录 为什么要克隆? 如何实现克隆 浅克 ...
- Java反射02 : Class对象获取的三种方式和通过反射实例化对象的两种方式
1.Class对象获取的三种方式 本文转载自:https://blog.csdn.net/hanchao5272/article/details/79361463 上一章节已经说过,一般情况下,Jav ...
- jQuery 获取DOM节点的两种方式
jQuery中包裹后的DOM对象实际上是一个数组,要获得纯粹的DOM对象可以有两种方式: 1.使用数组索引方式访问,例如: var dom = $(dom)[0]; 如: $("#id&qu ...
- 一步步分析Java深拷贝的两种方式-clone和序列化
今天遇到一道面试题,询问深拷贝的两种方法.主要就是clone方法和序列化方法.今天就来分析一下这两种方式如何实现深拷贝.如果想跳过解析的朋友,直奔"重点来了!"寻找答案. clon ...
- K:java中序列化的两种方式—Serializable或Externalizable
在java中,对一个对象进行序列化操作,其有如下两种方式: 第一种: 通过实现java.io.Serializable接口,该接口是一个标志接口,其没有任何抽象方法需要进行重写,实现了Serializ ...
随机推荐
- 使用python实现深度神经网络 3(转)
使用python实现深度神经网络 3 快速计算梯度的魔法--反向传播算法 快速计算梯度的魔法--反向传播算法 一.实验介绍 1.1 实验内容 第一次实验最后我们说了,我们已经学习了深度学习中的模型mo ...
- Python操作redis系列之 列表(list) (五)(转)
# -*- coding: utf-8 -*- import redis r =redis.Redis(host=") 1. Lpush 命令将一个或多个值插入到列表头部. 如果 key 不 ...
- 终止java线程的2种方法
1.使用一个volatile的共享变量 2.使用interrupt方法 import java.util.concurrent.TimeUnit; /** * ThreadTest */ public ...
- mac下卸载jdk
mac下安装软件很简单,但是卸载起来相对比较麻烦,下面进入正题: 首先你得知道你的电脑中安装了哪些jdk(mac可以安装多个jdk) 打开mac的终端,输入命令: ls /Library/Java/J ...
- Mybatis中自定义映射xml参数传递使用
在使用mybatis框架时,大多时候自动生成的mapper.xml文件能满足我们所需的数据库操作,但一些情况下还是需要我们自己写sql:为了加深印象,总结了下参数传递的方式以及各个关键字的含义如下: ...
- AYUI7 响应式开发
AYUI7 爱奇艺某页面 响应式DEMO,AY响应式框架在MVC中,使用起来xaml级别,支持 显示器水平/垂直/任意 显示: 大于宽度和大于高度 触发器,小于宽度和小于高度 触发器,每个触发器支持是 ...
- H+ 编辑tab页 保存后 刷新列表tab页 并关闭自已。tabA页调用tabB页的方法
//注:在contabs.js文件中 $(function () { }); 方法外 加入 //注: data-name="' + menuName + '" 这句是加入的自定义属 ...
- window.print控制打印样式
我们可能会去使用window.print()方法来打印页面,但是当我们遇到需要改变打印时候的字体大小等css样式的时候你可能会懵逼. 所以搜索成了我们的必经之路,我相信在网上搜索出来的最好的答案就是使 ...
- Java读取Excel内容
借助于apathe的poi.jar,由于上传文件不支持.jar所以请下载后将文件改为.jar,在应用程序中添加poi.jar包,并将需要读取的excel文件放入根目录即可 本例使用java来读取exc ...
- 企业和个人都需要的终极跨平台全端解决方案 UniApp
相信大家在平时开发过程中都会遇到这两类问题: 很多中小型企业要快速开发一个产品,这个产品至少需要覆盖平台范围为:ios.Android.web/H5.微信/支付宝小程序,那么需要的投入的人力成本.时间 ...