文章参考 https://www.cnblogs.com/acode/p/6306887.html

一、前提

1、使用clone()方法的类,必须实现Cloneable接口,

否则调用clone()方法时候,会抛出  CloneNotSupportedException

2、clone()为protected修饰符方法,所以如果想使用clone()方法,必须在子类中实现

二、实战

类关系(

Student:两个基础类型属性

一个引用类型属性)

1、创建一个Student类

@Data
public class Student implements Cloneable{ private String name; private int age; private Mother mother ; @Override
protected Object clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();
try {
Mother mother1 = (Mother)mother.clone();
student.setMother(mother1);
} catch (Exception e) {
e.printStackTrace();
}
return student;
}
}

2、创建一个Mother类

@Data
public class Mother implements Cloneable { private String name; private int age; @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

3、创建一个测试类

public class Test {

    public static void main(String[] args) throws  Exception {
//============初始化================
Mother mother = new Mother();
mother.setName("小王mama");
mother.setAge(40);
Student student = new Student();
student.setAge(1);
student.setName("小王");
student.setMother(mother);
//============克隆================
Student student2 = (Student)student.clone();
student2.setName("小李");
student2.setAge(2);
student2.getMother().setAge(45);
student2.getMother().setName("小李mama");
//============输出================
System.out.println(student);
System.out.println(student2);
}
}  

三、结果

Student(name=小王, age=1, mother=Mother(name=小王mama, age=40))
Student(name=小李, age=2, mother=Mother(name=小李mama, age=45))

四、分析

1、结果实现类深度克隆

2、如果在Student类的clone()方法中没有,进行Mother类的操作,则Mother属性只会进行引用操作

修改Student类中的clone()方法

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}

结果

Student(name=小王, age=1, mother=Mother(name=小李mama, age=45))
Student(name=小李, age=2, mother=Mother(name=小李mama, age=45))

3、歪门邪术(实现序列化接口,实现clone)  对象串行化,但是串行化却很耗时,在一些框架中,我们便可以感受到,它们往往将对象进行串行化后进行传递,耗时较多。

@Data
public class Student implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; private Mother mother ; public Object deepClone() throws IOException,
ClassNotFoundException {
// 将对象写到流里
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
// 从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
}
}
@Data
public class Mother implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; }

结果:深度克隆成功

Student(name=小王, age=1, mother=Mother(name=小王mama, age=40))
Student(name=小李, age=2, mother=Mother(name=小李mama, age=45))

java-深克隆和浅克隆的更多相关文章

  1. JAVA深克隆与浅克隆1

    复制就是得到一个副本 克隆就是复制一个对象的复本.但一个对象中可能有基本数据类型,如:int,long,float    等,也同时含有非基本数据类型如(数组,集合等)被克隆得到的对象基本类型的值修改 ...

  2. java深克隆与浅克隆

    2015.9.19 6:45   星期五    1

  3. java 深克隆(深拷贝)与浅克隆(拷贝)详解

    java深克隆和浅克隆 基本概念 浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所拷贝的对象,而不复制它所引用的对 ...

  4. Java克隆--深克隆与浅克隆的区别

    克隆,就是复制一个对象的副本,而克隆又分浅克隆和深克隆.浅克隆是指克隆得到的对象基本类型的值改变了,而源对象的值不会变.但如果被克隆对象引用类型的值改变了,那么源对象的值同样会改变,因为引用类型在栈内 ...

  5. Java中的深克隆和浅克隆

    为什么要克隆 首先思考一个问题, 为什么需要克隆对象? 直接new一个对象不行吗? 克隆的对象可能包含一些已经修改过的属性, 而new出来的对象的属性都还是初始化时候的值, 所以当需要一个新的对象来保 ...

  6. 浅谈Java中的深克隆和浅克隆(阿里面试)

    在最近的秋招中,阿里和多益网络都问到了这个问题,虽然很简单,但是我还是想总结一下,感兴趣的可以看一下我的个人博客网站(Spring+MyBatis+redis+nginx+mysql)(适合菜鸟),最 ...

  7. 【java开发系列】—— 深克隆和浅克隆

    Java支持我们对一个对象进行克隆,通常用在装饰模式和原型模式中.那么什么是深克隆,什么是浅克隆呢. [浅克隆],通常只是对克隆的实例进行复制,但里面的其他子对象,都是共用的. [深克隆],克隆的时候 ...

  8. Java对象的浅克隆和深克隆

    为什么需要克隆      在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B, 并且此后对B任何改动都不会影响到A中的值 ...

  9. JavaScript的深克隆与浅克隆

    JS数据类型分为两类: 基本类型(Number.Boolean.Undefined.Null.String.Symbol(ES6新加,此处不讨论))与引用类型(Object).原始类型存储的是对象的实 ...

  10. js深克隆与浅克隆

    定义: 浅克隆: 克隆对象的一层属性, 如果对象还有对象的话,里面的对象没有进行克隆,只是把地址给了别人.也可以理解为只是简单的克隆了躯体,但是没有得到其灵魂: 深克隆:克隆对象的多层属性,对象里面还 ...

随机推荐

  1. T-SQL:谓词和运算符(六)

    谓词一般有 where和having,check  谓词只计算 TRUE ,FALSE或者UNKNOWN  逻辑表达式  如 AND 和OR 1.IN 谓词的用法 SELECT orderid, em ...

  2. C# .aspx 页面更换命名空间

    1.选中命名空间,右键单击,选择重构,之后选择重命名.如下图: 2.弹出重命名对话框 3.重写你需要的名字,点击确定. 4.这里重点注意了,不可直接点击应用,否则你会后悔的.你必须对应的看看那个是否是 ...

  3. 8.并发容器ConcurrentHashMap#put方法解析

    jdk1.7.0_79 HashMap可以说是每个Java程序员用的最多的数据结构之一了,无处不见它的身影.关于HashMap,通常也能说出它不是线程安全的.这篇文章要提到的是在多线程并发环境下的Ha ...

  4. Does the C standard guarantee buffers are not touched past their null terminator?

    Question: In the various cases that a buffer is provided to the standard library's many string funct ...

  5. git常用命令以及如何与fork别人的仓库保持同步

    简单常用命令1.git status查看当前仓库是否有文件改动a:提示Your branch is up-to-date with 'origin/master'.nothing to commit, ...

  6. 解决VM提示:VMware Workstation cannot connect to the virtual machine. Make sure you have rights to run the program, access all directories the program uses, and access all directories for temporary files.

    问题: 在开启虚拟机的时候报: VMware Workstation cannot connect to the virtual machine. Make sure you have rights ...

  7. 谈谈web上各种图片应用的优缺点

    web中承载信息的主要方式就是图片与文字了,以下就是对一些web图片格式的优缺点进行归纳. 1.GIF GIF图是比较古老的web图片格式之一,可以追溯到1987,几乎所有的浏览器都支持这一种格式,老 ...

  8. Linux 操作系统主机名变成bogon怎么解决?

    主机名变成bogon怎么解决? by:授客 QQ:1033553122   一:使用hostname命令 [laiyu@localhost ~]$ hostname localhost.localdo ...

  9. Spring Boot Actuator认识

    概述 spring-boot-starter-actuator:是一个用于暴露自身信息的模块,主要用于监控与管理. 为了保证actuator暴露的监控接口的安全性,需要添加安全控制的依赖spring- ...

  10. SQL Server 全文索引介绍(转载)

    概述 全文引擎使用全文索引中的信息来编译可快速搜索表中的特定词或词组的全文查询.全文索引将有关重要的词及其位置的信息存储在数据库表的一列或多列中.全文索引是一种特殊类型的基于标记的功能性索引,它是由 ...