一.Cloneable 的用途 
  Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone()方法。如果没有implements Cloneable的类调用Object.clone()方法就会抛出CloneNotSupportedException。

二.克隆的分类 
  (1)浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。 
  (2)深克隆(deep clone),深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。

举例区别一下:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2中包含对C2(C1的copy)的引用。

三.克隆的举例 
  要让一个对象进行克隆,其实就是两个步骤: 
  1. 让该类实现java.lang.Cloneable接口; 
  2. 重写(override)Object类的clone()方法。

Demo:

1.浅克隆

public class Animal implements Cloneable{

    private int age;
private String name; public Object clone() throws CloneNotSupportedException{
return super.clone();
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

测试类:

public class TestMain {
public static void main(String[] args) throws Exception {
Animal animal1 = new Animal();
animal1.setAge(12);
animal1.setName("狮子"); Animal animal2 = (Animal) animal1.clone();
//animal2.setName("老虎"); System.out.println("类型比较:"+(animal1==animal2));
System.out.println("基本数据类型比较:"+(animal1.getAge()==animal2.getAge()));
System.out.println("引用数据类型地址比较:"+(animal1.getName()==animal2.getName()));
System.out.println("引用数据类型内容比较:"+(animal1.getName().equals(animal2.getName())));
System.out.println("引用数据类型内容:"+animal1.getName()+"/"+animal2.getName());
} }

输出结果:

类型比较:false
基本数据类型比较:true
引用数据类型地址比较:true
引用数据类型内容比较:true
引用数据类型内容:狮子/狮子

2.深克隆

public class Animal implements Cloneable{

    private int age;
private String name; public Object clone() throws CloneNotSupportedException{
Animal animal = (Animal) super.clone();
animal.name = new String(this.name);
return animal;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

测试类:

public class TestMain {
public static void main(String[] args) throws Exception {
Animal animal1 = new Animal();
animal1.setAge(12);
animal1.setName("狮子"); Animal animal2 = (Animal) animal1.clone();
//animal2.setName("老虎"); System.out.println("类型比较:"+(animal1==animal2));
System.out.println("基本数据类型比较:"+(animal1.getAge()==animal2.getAge()));
System.out.println("引用数据类型地址比较:"+(animal1.getName()==animal2.getName()));
System.out.println("引用数据类型内容比较:"+(animal1.getName().equals(animal2.getName())));
System.out.println("引用数据类型内容:"+animal1.getName()+"/"+animal2.getName());
} }

测试结果:

类型比较:false
基本数据类型比较:true
引用数据类型地址比较:false
引用数据类型内容比较:true
引用数据类型内容:狮子/狮子

总结:浅克隆是把该对象的基本数据及引用地址复制,深克隆是把该对象的基本数据以及对象copy到另一个地址

Cloneable测试的更多相关文章

  1. Java的一个高性能快速深拷贝方法。Cloneable?

    本人在设计数据库缓存层的时候,需要对数据进行深拷贝,这样用户操作的数据对象就是不共享的. 这个思路实际上和Erlang类似,就是用数据不共享解决并发问题. 1. 序列化? 原来的做法,是用序列化,我用 ...

  2. Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨

    Java对象克隆(Clone)及Cloneable接口.Serializable接口的深入探讨 Part I 没啥好说的,直接开始Part II吧. Part II 谈到了对象的克隆,就不得不说为什么 ...

  3. (转)Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨

    原文地址:http://blog.csdn.net/kenthong/article/details/5758884 Part I 没啥好说的,直接开始Part II吧. Part II 谈到了对象的 ...

  4. Java的四个标记接口:Serializable、Cloneable、RandomAccess和Remote接口

    一.概述 标记接口是一些没有属性和方法的接口,也是一种设计思想.Java中的一个标记接口表示的的是一种类的特性,实现了该标记接口的类则具有该特性.如实现了Serializable接口的类,表示这个类的 ...

  5. 分析轮子(九)- Cloneable.java

    注:玩的是JDK1.7版本 一:Cloneable.java 接口也是标记接口,所以,它没有任何方法和属性,实现此接口表示的意思是:可以调用 Object.java 类的 clone() 方法,进行简 ...

  6. 关于Java中的HashMap的深浅拷贝的测试与几点思考

    0.前言 工作忙起来后,许久不看算法,竟然DFA敏感词算法都要看好一阵才能理解...真是和三阶魔方还原手法一样,田园将芜,非常可惜啊. 在DFA算法中,第一步是需要理解它的数据结构,在此基础上,涉及到 ...

  7. Cloneable接口的作用与深度克隆与浅度克隆

    cloneable接口的作用 cloneable其实就是一个标记接口,只有实现这个接口后,然后在类中重写Object中的clone方法,然后通过类调用clone方法才能克隆成功,如果不实现这个接口,则 ...

  8. SignalR系列续集[系列8:SignalR的性能监测与服务器的负载测试]

    目录 SignalR系列目录 前言 也是好久没写博客了,近期确实很忙,嗯..几个项目..头要炸..今天忙里偷闲.继续我们的小系列.. 先谢谢大家的支持.. 我们来聊聊SignalR的性能监测与服务器的 ...

  9. Apache Ignite之集群应用测试

    集群发现机制 在Ignite中的集群号称是无中心的,而且支持命令行启动和嵌入应用启动,所以按理说很简单.而且集群有自动发现机制感觉对于懒人开发来说太好了,抱着试一试的心态测试一下吧. 在Apache ...

随机推荐

  1. mysql函数使用报错

    This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de 错误解决办法 解决办法也有两种,第一种是在创建 ...

  2. 【LOJ】#3042. 「ZJOI2019」麻将

    LOJ#3042. 「ZJOI2019」麻将 如何判定一个集合牌有没有胡的子集是不是胡的 就用一个\(dp[j][k][0/1]\)表示有j个连续两个的串,有k个连续1个串,有没有对子,再记一下这个集 ...

  3. P1373 小a和uim之大逃离(DP)

    (点击此处查看原题) 题意 中文题,题意看题面吧. 解题思路 注意到我们只能向右和下移动,由此想到开二维的dp数组dp[i][j],代表当前所在位置 我们需要让两人取数的差值为0,由于起点和走法的不同 ...

  4. LC 155 Min Stack

    问题描述 Design a stack that supports push, pop, top, and retrieving the minimum element in constant tim ...

  5. 安装echo框架

    视频地址: https://www.bilibili.com/video/av63492462?p=31 echo文档地址: https://echo.labstack.com/guide/insta ...

  6. python 文件写入

    def write_file(): """ 文件写入""" file_name = "wri2te_test.txt" ...

  7. drf的三大认证

    目录 三大认证任务分析 auth组件的认证权限六表 自定义User表分析 源码分析 认证与权限工作原理 源码分析 认证模块工作原理 权限模块工作原理 admin关联自定义用户表 自定义认证.权限类 用 ...

  8. Dreamoon and Strings CodeForces - 477C (字符串dp)

    大意: 给定字符串$s$, $p$, 对于$0\le x\le |s|$, 求$s$删除$x$个字符后, $p$在$s$中的最大出现次数. 显然答案是先递增后递减的, 那么问题就转化求最大出现次数为$ ...

  9. Array Product CodeForces - 1042C (细节)

    #include <iostream> #include <sstream> #include <algorithm> #include <cstdio> ...

  10. Scala学习十一——操作符

    一.本章要点 标识符由字母,数字或运算符构成 一元和二元操作符其实是方法调用 操作符优先级取决于第一个字符,而结合性取决于最后一个字符 apply和update方法在对expr(args)表达式求值时 ...