对象实现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的更多相关文章

  1. Java中对象拷贝的两种方式

    引用的拷贝 //引用拷贝 private static void copyReferenceObject(){ Person p = new Person(23, "zhang") ...

  2. 检测对象类型的两种方式,constructor属性和instanceof

    //本例是为了记录检测对象类型的两种方式,即constructor属性和instanceof操作符.详见<高三>P145        function Person(name, age, ...

  3. Redis:存储对象的两种方式(序列化和json字符串)

    方式一:序列化操作   public class SerializeUtil {   /*   * 序列化   * */   public static byte[] serizlize(Object ...

  4. JVM中对象访问定位两种方式

    1.通过句柄方式访问, 在Java堆中分出一块内存进行存储句柄池,这样的话,在栈中存储的是句柄的地址 优点: 当对象移动的时候(垃圾回收的时候移动很普遍),这样值需要改变句柄中的指针,但是栈中的指针不 ...

  5. java 的对象拷贝(有深浅拷贝两种方式,深拷贝实现的两种方式(逐层实现cloneable接口,序列化的方式来实现))

    Java提高篇--对象克隆(复制)(转自:http://www.cnblogs.com/Qian123/p/5710533.html#_label0)   阅读目录 为什么要克隆? 如何实现克隆 浅克 ...

  6. Java反射02 : Class对象获取的三种方式和通过反射实例化对象的两种方式

    1.Class对象获取的三种方式 本文转载自:https://blog.csdn.net/hanchao5272/article/details/79361463 上一章节已经说过,一般情况下,Jav ...

  7. jQuery 获取DOM节点的两种方式

    jQuery中包裹后的DOM对象实际上是一个数组,要获得纯粹的DOM对象可以有两种方式: 1.使用数组索引方式访问,例如: var dom = $(dom)[0]; 如: $("#id&qu ...

  8. 一步步分析Java深拷贝的两种方式-clone和序列化

    今天遇到一道面试题,询问深拷贝的两种方法.主要就是clone方法和序列化方法.今天就来分析一下这两种方式如何实现深拷贝.如果想跳过解析的朋友,直奔"重点来了!"寻找答案. clon ...

  9. K:java中序列化的两种方式—Serializable或Externalizable

    在java中,对一个对象进行序列化操作,其有如下两种方式: 第一种: 通过实现java.io.Serializable接口,该接口是一个标志接口,其没有任何抽象方法需要进行重写,实现了Serializ ...

随机推荐

  1. 不要使用Integer做HashMap的key,尤其在json序列化的时候

    使用redisson cache来实现一个缓存功能,缓存省市县的名称,key是区域编码,integer,value是name.结果取的时候,怎么都取不出. Map<Integer, String ...

  2. Spark(四十五):Schema Registry

    很多时候在流数据处理时,我们会将avro格式的数据写入到kafka的topic,但是avro写入到kafka的时候,数据有可能会与版本升级,也就是schema发生变化,此时如果消费端,不知道哪些数据的 ...

  3. 遇到一个git branch很奇怪的问题

    最近,同事做了一个自动化的打包平台,但我发现里面的分支竟然有重复的,还有一些已经删除的branch. 比如,我已经删除了一个 test分支,在工程 game 目录下(已输入 git pull),输入: ...

  4. 自动化web前端测试,自动登录网站.目前发现最靠谱的方法是imacros

    imacros免费版 登录宏代码的示例: //首先登出URL GOTO=http://yoursite/logout.html//打开登录页面URL GOTO=http://yoursite/logi ...

  5. MySQL遇到Deadlock found when trying to get lock,解决方案

    最近遇到一个MYSQL update语句出现Deadlock found when trying to get lock的问题,分析一下原因. 什么情况下会出现Deadlock found when ...

  6. mybatis整合hikariCP(非spring)

    mybatis整合hikariCP(非spring) 一.配置hikariCP典型的配置文件hikariPool.properties jdbcUrl=jdbc:mysql://localhost:3 ...

  7. mysql视图详解 mysql视图

    目录 22.1. ALTER VIEW语法 22.2. CREATE VIEW语法 22.3. DROP VIEW语法 22.4. SHOW CREATE VIEW语法 本章讨论了下述主题: ·    ...

  8. 突破这个四个阶段年薪没有50W,还好意思说是搞Java的?

    该视频教程总共分为四个阶段来学习.逐步进阶,并且还会不定期更新.我简介一下每一个阶段的视频资源,学习顺序不分先后. 第一阶段 第一阶段主要从 svn/git 版本号控制.Java高并发.JVM虚拟机. ...

  9. 【MySQL (六) | 详细分析MySQL事务日志redo log】

    Reference:  https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html 引言 为了最大程度避免数据写入时 IO ...

  10. spring相关面试题

    1.spring有依赖的bean,怎么加载? 2.spring怎么解决循环依赖? https://blog.csdn.net/u010853261/article/details/77940767 h ...