java中的深复制和浅复制

使用Hutool来实现深拷贝 使用Hutool工具类来实现深拷贝,本质是使用序列化的方式来实现的。 Hutool链接 阅读详情

java中的深复制和浅复制

Java 语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念。并且由于Java不能通过简单 的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象。本文会让你了解什么是影子clone与深度clone,认识它 们的区别、优点及缺点。 

      看到这个标题,是不是有点困惑:Java语 言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写成的代码不亚于使用 早已臭名昭著的"GOTO"语句。Java放弃指针的概念绝对是极其明智的。但这只是在Java语言中没有明确的指针定义,实质上每一个new语句返回的 都是一个指针的引用,只不过在大多时候Java中不用关心如何操作这个"指针",更不用象在操作C++的指针那样胆战心惊。唯一要多多关心的是在给函数传 递对象的时候。

  1. package com.zoer.src;  
  2.   
  3. public class ObjRef {  
  4.     Obj aObj = new Obj();  
  5.     int aInt = 11;  
  6.   
  7.     public void changeObj(Obj inObj) {  
  8.         inObj.str = "changed value";  
  9.     }  
  10.   
  11.     public void changePri(int inInt) {  
  12.         inInt = 22;  
  13.     }  
  14.   
  15.     public static void main(String[] args) {  
  16.         ObjRef oRef = new ObjRef();  
  17.   
  18.         System.out.println("Before call changeObj() method: " + oRef.aObj);  
  19.         oRef.changeObj(oRef.aObj);  
  20.         System.out.println("After call changeObj() method: " + oRef.aObj);  
  21.   
  22.         System.out.println("==================Print Primtive=================");  
  23.         System.out.println("Before call changePri() method: " + oRef.aInt);  
  24.         oRef.changePri(oRef.aInt);  
  25.         System.out.println("After call changePri() method: " + oRef.aInt);  
  26.   
  27.     }  
  28. }  

 

  1. package com.zoer.src;  
  2.   
  3. public class Obj {  
  4.   
  5.     String str = "init value";  
  6.   
  7.     public String toString() {  
  8.         return str;  
  9.     }  
  10. }  

      这段代码的主要部分调用了两个很相近的方法,changeObj()和changePri()。唯一不同的是它们一个把对象作为输入参数,另一个把 Java中的基本类型int作为输入参数。并且在这两个函数体内部都对输入的参数进行了改动。看似一样的方法,程序输出的结果却不太一样。 changeObj()方法真正的把输入的参数改变了,而changePri()方法对输入的参数没有任何的改变。 

      从这个例子知道Java对对象和基本的数据类型的处理是不一样的。和C语言一样,当把Java的基本数据类型(如int,char,double等)作为入口参数传给函数体的时候,传入的参数在函数体内部变成了局部变量,这个局部变量是输入参数的一个拷贝,所有的函数体内部的操作都是针对这个拷贝的操作,函数执行结束后,这个局部变量也就完成了它的使命,它影响不到作为输入参数的变量。这种方式的参数传递被称为"值传递"。而在Java中用对象作为入口参数的传递则缺省为"引用传递",也就是说仅仅传递了对象的一个"引用",这个"引用"的概念同C语言中的指针引用是一样的。当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。 

      除了在函数传值的时候是"引用传递",在任何用"="向对象变量赋值的时候都是"引用传递"。就是类似于给变量再起一个别名。两个名字都指向内存中的同一个对象。
      在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的。在Java语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但实现clone()方法是其中最简单,也是最高效的手段。
      Java的所有类都默认继承java.lang.Object类,在java.lang.Object类中有一个方法clone()。JDK API的说 明文档解释这个方法将返回Object对象的一个拷贝。要说明的有两点:一是拷贝对象返回的是一个新对象,而不是一个引用。二是拷贝对象与用new操作符 返回的新对象的区别就是这个拷贝已经包含了一些原来对象的信息,而不是对象的初始信息。
      怎样应用clone()方法? 

      一个很典型的调用clone()代码如下: 

  1. public class CloneClass implements Cloneable {  
  2.     public int aInt;  
  3.   
  4.     public Object clone() {  
  5.         CloneClass o = null;  
  6.         try {  
  7.             o = (CloneClass) super.clone();  
  8.         } catch (CloneNotSupportedException e) {  
  9.             e.printStackTrace();  
  10.         }  
  11.         return o;  
  12.     }  
  13. }  

      有三个值得注意的地方,一是希望能实现clone功能的CloneClass类实现了Cloneable接口,这个接口属于java.lang 包,java.lang包已经被缺省的导入类中,所以不需要写成java.lang.Cloneable。另一个值得请注意的是重载了clone()方 法。最后在clone()方法中调用了super.clone(),这也意味着无论clone类的继承结构是什么样的,super.clone()直接或间接调用了java.lang.Object类的clone()方法。下面再详细的解释一下这几点。       应该说第三点是最重要的,仔细观察一下Object类的clone()一个native方法,native方法的效率一般来说都是远高于java中的非native方法。这也解释了为什么要用Object中clone()方法而不是先new一个类,然后把原始对象中的信息赋到新对象中,虽然这也实现了clone功能。对于第二点,也要观察Object类中的clone()还是一个protected属 性的方法。这也意味着如果要应用clone()方法,必须继承Object类,在Java中所有的类是缺省继承Object类的,也就不用关心这点了。然 后重载clone()方法。还有一点要考虑的是为了让其它类能调用这个clone类的clone()方法,重载之后要把clone()方法的属性设置为public。
       那么clone类为什么还要实现Cloneable接口呢?稍微注意一下,Cloneable接口是不包含任何方法的!其实这个接口仅仅是一个标志,而 且这个标志也仅仅是针对Object类中clone()方法的,如果clone类没有实现Cloneable接口,并调用了Object的clone() 方法(也就是调用了super.Clone()方法),那么Object的clone()方法就会抛出 CloneNotSupportedException异常。 
      以上是clone的最基本的步骤,想要完成一个成功的clone,还要了解什么是"影子clone"和"深度clone"。 
      什么是影子clone? 

  1. package com.zoer.src;  
  2.   
  3. class UnCloneA {  
  4.     private int i;  
  5.   
  6.     public UnCloneA(int ii) {  
  7.         i = ii;  
  8.     }  
  9.   
  10.     public void doublevalue() {  
  11.         i *= 2;  
  12.     }  
  13.   
  14.     public String toString() {  
  15.         return Integer.toString(i);  
  16.     }  
  17. }  
  18.   
  19. class CloneB implements Cloneable {  
  20.     public int aInt;  
  21.     public UnCloneA unCA = new UnCloneA(111);  
  22.   
  23.     public Object clone() {  
  24.         CloneB o = null;  
  25.         try {  
  26.             o = (CloneB) super.clone();  
  27.         } catch (CloneNotSupportedException e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.         return o;  
  31.     }  
  32. }  
  33.   
  34. public class ObjRef {  
  35.     public static void main(String[] a) {  
  36.         CloneB b1 = new CloneB();  
  37.         b1.aInt = 11;  
  38.         System.out.println("before clone,b1.aInt = " + b1.aInt);  
  39.         System.out.println("before clone,b1.unCA = " + b1.unCA);  
  40.   
  41.         CloneB b2 = (CloneB) b1.clone();  
  42.         b2.aInt = 22;  
  43.         b2.unCA.doublevalue();  
  44.         System.out.println("=================================");  
  45.         System.out.println("after clone,b1.aInt = " + b1.aInt);  
  46.         System.out.println("after clone,b1.unCA = " + b1.unCA);  
  47.         System.out.println("=================================");  
  48.         System.out.println("after clone,b2.aInt = " + b2.aInt);  
  49.         System.out.println("after clone,b2.unCA = " + b2.unCA);  
  50.     }  
  51. }  

       输出结果:

before clone,b1.aInt = 11
before clone,b1.unCA = 111
=================================
after clone,b1.aInt = 11
after clone,b1.unCA = 222
=================================
after clone,b2.aInt = 22
after clone,b2.unCA = 222

       输出的结果说明int类型的变量aInt和UnCloneA的实例对象unCA的clone结果不一致,int类型是真正的被clone了,因为改变了 b2中的aInt变量,对b1的aInt没有产生影响,也就是说,b2.aInt与b1.aInt已经占据了不同的内存空间,b2.aInt是 b1.aInt的一个真正拷贝。相反,对b2.unCA的改变同时改变了b1.unCA,很明显,b2.unCA和b1.unCA是仅仅指向同一个对象的不同引用!从中可以看出,调用Object类中clone()方法产生的效果是:先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内容。对基本数据类型,这样的操作是没有问题的,但对非基本类型变量,我们知道它们保存的仅仅是对象的引用,这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。 

       大多时候,这种clone的结果往往不是我们所希望的结果,这种clone也被称为"影子clone"。要想让b2.unCA指向与b2.unCA不同的对象,而且b2.unCA中还要包含b1.unCA中的信息作为初始信息,就要实现深度clone。
       怎么进行深度clone? 
       把上面的例子改成深度clone很简单,需要两个改变:一是让UnCloneA类也实现和CloneB类一样的clone功能(实现Cloneable 接口,重载clone()方法)。二是在CloneB的clone()方法中加入一句 o.unCA = (UnCloneA)unCA.clone(); 

 

  1. package com.zoer.src;  
  2.   
  3. class UnCloneA implements Cloneable {  
  4.     private int i;  
  5.   
  6.     public UnCloneA(int ii) {  
  7.         i = ii;  
  8.     }  
  9.   
  10.     public void doublevalue() {  
  11.         i *= 2;  
  12.     }  
  13.   
  14.     public String toString() {  
  15.         return Integer.toString(i);  
  16.     }  
  17.   
  18.     public Object clone() {  
  19.         UnCloneA o = null;  
  20.         try {  
  21.             o = (UnCloneA) super.clone();  
  22.         } catch (CloneNotSupportedException e) {  
  23.             e.printStackTrace();  
  24.         }  
  25.         return o;  
  26.     }  
  27. }  
  28.   
  29. class CloneB implements Cloneable {  
  30.     public int aInt;  
  31.     public UnCloneA unCA = new UnCloneA(111);  
  32.   
  33.     public Object clone() {  
  34.         CloneB o = null;  
  35.         try {  
  36.             o = (CloneB) super.clone();  
  37.         } catch (CloneNotSupportedException e) {  
  38.             e.printStackTrace();  
  39.         }  
  40.         o.unCA = (UnCloneA) unCA.clone();  
  41.         return o;  
  42.     }  
  43. }  
  44.   
  45. public class CloneMain {  
  46.     public static void main(String[] a) {  
  47.         CloneB b1 = new CloneB();  
  48.         b1.aInt = 11;  
  49.         System.out.println("before clone,b1.aInt = " + b1.aInt);  
  50.         System.out.println("before clone,b1.unCA = " + b1.unCA);  
  51.   
  52.         CloneB b2 = (CloneB) b1.clone();  
  53.         b2.aInt = 22;  
  54.         b2.unCA.doublevalue();  
  55.         System.out.println("=================================");  
  56.         System.out.println("after clone,b1.aInt = " + b1.aInt);  
  57.         System.out.println("after clone,b1.unCA = " + b1.unCA);  
  58.         System.out.println("=================================");  
  59.         System.out.println("after clone,b2.aInt = " + b2.aInt);  
  60.         System.out.println("after clone,b2.unCA = " + b2.unCA);  
  61.     }  
  62. }  

输出结果:

before clone,b1.aInt = 11
before clone,b1.unCA = 111
=================================
after clone,b1.aInt = 11
after clone,b1.unCA = 111
=================================
after clone,b2.aInt = 22
after clone,b2.unCA = 222

      可以看出,现在b2.unCA的改变对b1.unCA没有产生影响。此时b1.unCA与b2.unCA指向了两个不同的UnCloneA实例,而且在 CloneB b2 = (CloneB)b1.clone();调用的那一刻b1和b2拥有相同的值,在这里,b1.i = b2.i = 11。 

        要知道不是所有的类都能实现深度clone的。例如,如果把上面的CloneB类中的UnCloneA类型变量改成StringBuffer类型,看一下JDK API中关于StringBuffer的说明,StringBuffer没有重载clone()方法,更为严重的是StringBuffer还是一个final类, 这也是说我们也不能用继承的办法间接实现StringBuffer的clone。如果一个类中包含有StringBuffer类型对象或和 StringBuffer相似类的对象,我们有两种选择:要么只能实现影子clone,要么就在类的clone()方法中加一句(假设是 SringBuffer对象,而且变量名仍是 unCA): o.unCA = new StringBuffer(unCA.toString()); //原来的 是:o.unCA = (UnCloneA)unCA.clone(); 

       还要知道的是除了基本数据类型能自动实现深度clone以外,String对象是一个例外,它clone后的表现好象也实现了深度clone,虽然这只是一个假象,但却大大方便了我们的编程。 
       Clone中String和StringBuffer的区别 
       应该说明的是,这里不是着重说明String和StringBuffer的区别,但从这个例子里也能看出String类的一些与众不同的地方。 
       下面的例子中包括两个类,CloneC类包含一个String类型变量和一个StringBuffer类型变量,并且实现了clone()方法。在 StrClone类中声明了CloneC类型变量c1,然后调用c1的clone()方法生成c1的拷贝c2,在对c2中的String和 StringBuffer类型变量用相应的方法改动之后打印结果: 

 

  1. package com.zoer.src;  
  2.   
  3. class CloneC implements Cloneable {  
  4.     public String str;  
  5.     public StringBuffer strBuff;  
  6.   
  7.     public Object clone() {  
  8.         CloneC o = null;  
  9.         try {  
  10.             o = (CloneC) super.clone();  
  11.         } catch (CloneNotSupportedException e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.         return o;  
  15.     }  
  16.   
  17. }  
  18.   
  19. public class StrClone {  
  20.     public static void main(String[] a) {  
  21.         CloneC c1 = new CloneC();  
  22.         c1.str = new String("initializeStr");  
  23.         c1.strBuff = new StringBuffer("initializeStrBuff");  
  24.         System.out.println("before clone,c1.str = " + c1.str);  
  25.         System.out.println("before clone,c1.strBuff = " + c1.strBuff);  
  26.   
  27.         CloneC c2 = (CloneC) c1.clone();  
  28.         c2.str = c2.str.substring(0, 5);  
  29.         c2.strBuff = c2.strBuff.append(" change strBuff clone");  
  30.         System.out.println("=================================");  
  31.         System.out.println("after clone,c1.str = " + c1.str);  
  32.         System.out.println("after clone,c1.strBuff = " + c1.strBuff);  
  33.         System.out.println("=================================");  
  34.         System.out.println("after clone,c2.str = " + c2.str);  
  35.         System.out.println("after clone,c2.strBuff = " + c2.strBuff);  
  36.     }  
  37. }  

执行结果:

  1. before clone,c1.str = initializeStr  
  2. before clone,c1.strBuff = initializeStrBuff  
  3. =================================  
  4. after clone,c1.str = initializeStr  
  5. after clone,c1.strBuff = initializeStrBuff change strBuff clone  
  6. =================================  
  7. after clone,c2.str = initi  
  8. after clone,c2.strBuff = initializeStrBuff change strBuff clone  

        打印的结果可以看出,String类型的变量好象已经实现了深度clone,因为对c2.str的改动并没有影响到c1.str!难道Java把 Sring类看成了基本数据类型?其实不然,这里有一个小小的把戏,秘密就在于c2.str = c2.str.substring(0,5)这一语句! 实质上,在clone的时候c1.str与c2.str仍然是引用,而且都指向了同一个String对象。但在执行 c2.str = c2.str.substring(0,5)的时候,它作用相当于生成了一个新的String类型,然后又赋回给c2.str。这是因 为String被Sun公司的工程师写成了一个不可更改的类(immutable class),在所有String类中的函数都不能更改自身的值。

Java深拷贝与浅拷贝 1、把一个对象从内存中完整的复制一份(包括内存地址)出来,从堆内存中开辟一个新的区域存放新对象,修改二者任意对象属性值不会影响另一个对象,互相隔离,互不影响。只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存, 所以如果其中一个对象改变了这个地址中的属性值,就会影响到另一个对象的属性值。深拷贝是将一个对象从内存中完整的复制一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象属性值不会影响原对象。【1】把一个对象从内存中完整的复制一份出来,从堆内存中开辟一个新的区域存放新对象。 阅读详情

相关推荐

深拷贝、浅拷贝

深拷贝、浅拷贝

lydms的博客 7471

hutool实现深拷贝

【代码】hutool实现深拷贝。

weixin_63865318的博客 3907

ECharts 实现世界地图

效果图 源代码(仅供参考) <template> <div class="echarts"> <div class="className" id="id" style="width: 100%; height: 450px" ref="myEchart" ></div> </div> </template> <script lang="ts"> imp

EsquireY的博客 4871

【Java 工具类 Hutool】Hutool 克隆功能的使用

我们知道,JDK中的Cloneable接口只是一个空接口,并没有定义成员,它存在的意义仅仅是指明一个类的实例化对象支持位复制(就是对象克隆),如果不实现这个类,调用对象的clone()方法就会抛出CloneNotSupportedException异常。而且,因为clone()方法在Object对象中,返回值也是Object对象,因此克隆后我们需要自己强转下类型。

激流丶的博客 3939

OnlyOffice Docker部署踩坑实录:解决Nginx反向代理导致的editor.bin下载失败

本文详细解析了在Docker中部署OnlyOffice时,因Nginx反向代理配置不当导致editor.bin下载失败的常见问题。通过分析问题根源,提供了从Nginx代理配置、Docker网络设置到OnlyOffice容器内部调整的完整解决方案,并分享了实战调试技巧与性能优化建议,帮助用户彻底解决这一部署难题。

wine的专栏 523

影刀RPA之成绩批量查询系统

自动化登录账号,读取数据表中内容去填写信息去查询,并判断多个数据不同的页面去不同的读取查询结果内容,如考生各项信息与各科成绩,总分和查询时间,采集出来到指定的数据表格中,等待时间并依次循环运行。主要功能。

2201_75330891的博客 1082

Java中的深复制和浅复制

深复制和浅复制也称为深拷贝和浅拷贝。简单的说就是创建一个和当前对象一模一样的对象。在日常编码的过程中使用的几率并不多,但在面试中却会被经常问到。 了解深复制和浅复制的原理后,可以帮助我们对Java中的值传递和引用传递有更深刻的理解。 浅复制 下面的实例中,我们创建一个原始类Monster,调用对象的clone方法复制一个新的对象。 注意:要调用对象的clone方法,需要让类实现Cloneable接...

LaoJiuJun的博客 229

香橙派R1 Plus LTS变身无线AP/客户端:手把手教你用RTL8811CU和MT7601U网卡刷OpenWRT

本文详细介绍了如何将香橙派R1 Plus LTS开发板通过RTL8811CU和MT7601U两款USB无线网卡刷入OpenWRT系统,实现无线AP热点发射与客户端接入的双重功能。从硬件选型、驱动安装到双网卡协同配置,提供完整的实战指南,帮助用户快速搭建稳定高效的无线网络解决方案。

weixin_30919429的博客 408

Java中的浅复制和深复制

一、浅复制与深复制概念 (1)浅复制 浅复制会复制“被复制对象”基本类型的值和对象的引用。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 (2)深复制 深复制会复制“被复制对象”基本类型的值,对象的引用将重新指向一个被复制过的新对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。 二、clone()、Cloneable和Serialiable (1)clone()...

鹿与森的博客 624

Android15音频进阶之音效配置与解析(一百三十一)

本篇目的:Android15音频进阶之音效配置与解析。

Android系统攻城狮 2146

浅谈Java中的浅复制和深复制

浅谈Java中的浅克隆和深克隆1-clone、Cloneable和Serialiable什么是浅复制?什么是深复制?两者有何区别?要弄清楚这些问题,一切都要从Object的一个方法clone方法和两个标记接口Cloneable和Serializable谈起!首先来看看clone方法,clone方法是Java中根父类Object的一个方法,定义如下:protected native Object c...

weixin_38810239的博客 5068

从 QQ 聊天到 AI Agent:AstrBot + NapCat 接入 DeepSeek

<think>我们根据要求,根据提供的内容生成≤150字的文章摘要。内容是关于在Windows上使用Docker部署AstrBot+NaPCat,配置DeepSeek,实现QQ AI机器人。摘要需简洁概括主要步骤和结论。注意字数。</think>在Windows 11上通过Docker一键部署AstrBot与NapCat,实现QQ机器人。NapCat扫码登录QQ,AstrBot接入并配置DeepSeek API,完成AI对话。后续可扩展人格、插件及MCP工具,并通过cpolar提供公网管理入口,打造可扩展的

天道酬勤 1万+

对Java中的深复制和浅复制的一些理解

Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念。并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象。浅复制与深复制概念浅复制(浅克隆) :被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象

Megustas_JJC的博客 717

OpenCV C++ 图像处理实战 ——《基于轮廓比对的缺陷检测》

本文使用OpenCV C++ 实现基于轮廓比对的缺陷检测。

Zero___Chen的博客 1144

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

java中的浅复制和深复制

浅复制:只复制基本数据类型,对于引用类型不能实现浅复制的效果。 代码: package com.qf.day13.price.object; public class TestObject { public static void main(String[] args) { Student stu1 = new Student("张三",22); stu1.name="李四"; System.out.println(stu1); Student stu2 =(Student) stu1.c

haidi8 706

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

java clone 中的浅复制和深复制

什么是浅复制? 首先,浅复制会创建一个新对象,这个新的对象各个字段的值会从原始对象复制过来,如果某个字段是引用其他的对象,那么仅仅复制此对象在内存中的引用地址。 图1 如图1 所示,对象 MainObject1 有一个 int 类型的字段 Field1 和一个字段引用 ContainObject1对象,被克隆的新对象是 MainObject2, MainObject2 有一个 int

独 coding 乐不如众 coding 乐 834

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

java中的clone(深复制和浅复制)

浅复制:被复制对象的所有变量都含有与原来对象想通过的值,而所有对其他对象的引用仍然指向原来的对象,换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。 深复制:被复制对象的所有变量都含有与原来对象相同的值,除去那些引用其他对象的变量,那些引用其他对象的变量将指向被复制的新对象,而不再是原有的那些被引用的对象,换言之,深复制的对象所引用的对象都复制了一遍。 使用clone()方法

XiaopinOo的博客 448

java中的clone:深复制和浅复制

参考文章: java中的深复制和浅复制 : http://blog.youkuaiyun.com/naughty610/article/details/6598943 Java 深拷贝和浅拷贝: http://www.cnblogs.com/mengdd/archive/2013/02/20/2917971.html 

dreajay的专栏 1561
上一篇: getClassLoader()和getContextClassLoader()的区别
下一篇: 深入理解LinkedHashMap和LRU缓存
架构师的清醒
博客等级 码龄14年 291粉丝 397原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值