对象实现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. 正則表達式 - C语言

    http://blog.csdn.net/pipisorry/article/details/37073843 sscanf/scanf正则使用方法 %[ ] 的使用方法:%[ ]表示要读入一个字符集 ...

  2. mysql sql执行慢 分析过程

    摘自: https://blog.csdn.net/zhuzaijava/article/details/77935200 为了验证select 1 与 select 1 from tableName ...

  3. 使用wrk进行压力测试

    最近需要对新的服务进行压力测试.比较了ab和jemeter以及wrk.最终选择wrk来作为压力测试工具,可以把cpu压到100%. 官方源码: https://github.com/wg/wrk 安装 ...

  4. 终止java线程的2种方法

    1.使用一个volatile的共享变量 2.使用interrupt方法 import java.util.concurrent.TimeUnit; /** * ThreadTest */ public ...

  5. shell脚本启动语法错误syntax error near unexpected token '{

    执行shell脚本时失败,报语法错误,但脚本内容检查正常 原因为该脚本是在非Linux系统下编辑之后放到系统执行的,文件模式类型非Linux系统匹配的模式类型. 查看文件的模式类型 显示文件的模式类型 ...

  6. java字符串的替换replace、replaceAll、replaceFirst的区别详解

    如果不是刚刚复习了下正则表达式,我可能也不会注意到,原来String的replaceAll跟replaceFirst用到了正则表达式! 不多解释,看代码: String s = "my.te ...

  7. [转]调试利器-SSH隧道

    在开发微信公众号或小程序的时候,由于微信平台规则的限制,部分接口需要通过线上域名才能正常访问.但我们一般都会在本地开发,因为这能快速的看到源码修改后的运行结果.但当涉及到需要调用微信接口时,由于不和你 ...

  8. 表表达式,Substring, CharIndex, 多行数据变同一行的用法

    参考: https://www.cnblogs.com/cnki/p/9561427.html https://www.cnblogs.com/johnwood/p/6386613.html 1.表1 ...

  9. AWS免费套餐服务器部署NETCORE网站

    之前的linode充了5美元,一个月就用完了,还是创建的最便宜的服务器的!!! 以前一直想用用aws的所谓的免费套餐服务器的,现在linode过期了,可以试着用用了 下面是我的操作流程,包含错误及解决 ...

  10. 再谈Promise

    方法 构造函数 接受的参数是一个带两个Function参数的函数,实际的异步代码编写在这个函数里,成功后调用第一个参数,失败调用第二个: Promise.prototype.catch 当构造函数里调 ...