java深克隆方法是什么,java中的浅克隆和深克隆是什么
老铁们,大家好,相信还有很多朋友对于java深克隆方法是什么和java中的浅克隆和深克隆是什么的相关问题不太懂,没关系,今天就由我来为大家分享分享java深克隆方法是什么以及java中的浅克隆和深克隆是什么的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!
java中深克隆与浅克隆的区别
能够给你做出解释,我很荣幸!!献丑了:
A、你说的很对,无论是深克隆还是浅克隆都是克隆,既然是克隆就必然会产生一个全新的对象,这个全新的对象和原对象的保持一致性的深浅取决于克隆的深度。但需要始终明确的一点是克隆的对象与源对象没有任何关系,它在堆中是一个独立的实体,占据独立的内存地址,与原对象没有任何引用与指向关系。这个新生的对象是在源对象被克隆时由JVM运行时环境在调用类加载器时通过反射创建出来的。
B、深克隆与浅克隆的区别:深克隆的过程是通过序列化来完成的,而序列化的过程可以将对象及所牵涉的所有引用链中的对象一起通过字节流的方式转移到特定的存储单元中(这个存储单元可以是内存也可以是硬盘,对于克隆通常是序列化至内存),再通过反序列化的过程读出这些序列化的字节流重构出对象,这样就完成了一个新对象的产生。而浅克隆不用序列化,这种克隆方式仅仅只是将指定的当前对象复制出来一个,这种复制过程不包括原对象引用的各个对象
C、克隆出的对象与原对象具有相同的属性及方法,但克隆的对象与原对象是属于两个不同的独立对象,因此二者占据内存中不同的空间地址。这就好比两个人长的极为相像但他们毕竟还是属于两个人,可以住在不同的场所。
java如何实现对象的深克隆
/**定义用户**/
publicclassUser{
privateStringname;
privateAddressaddress;
//constructors,gettersandsetters
}
/**地址**/
publicclassAddress{
privateStringcity;
privateStringcountry;
//constructors,gettersandsetters
}
重载clone()方法
Object父类有个clone()的拷贝方法,不过它是protected类型的,
我们需要重写它并修改为public类型。
除此之外,子类还需要实现Cloneable接口来告诉JVM这个类是可以拷贝的。
重写代码
让我们修改一下User类,Address类,实现Cloneable接口,使其支持深拷贝。
/**
*地址
*/
publicclassAddressimplementsCloneable{
privateStringcity;
privateStringcountry;
//constructors,gettersandsetters
@Override
publicAddressclone()throwsCloneNotSupportedException{
return(Address)super.clone();
}
}
/**
*用户
*/
publicclassUserimplementsCloneable{
privateStringname;
privateAddressaddress;
//constructors,gettersandsetters
@Override
publicUserclone()throwsCloneNotSupportedException{
Useruser=(User)super.clone();
user.setAddress(this.address.clone());
returnuser;
}
}
需要注意的是,super.clone()其实是浅拷贝,
所以在重写User类的clone()方法时,address对象需要调用address.clone()重新赋值。
扩展:
为什么要克隆?
大家先思考一个问题,为什么需要克隆对象?直接new一个对象不行吗?
答案是:克隆的对象可能包含一些已经修改过的属性,而new出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠clone方法了。那么我把这个对象的临时属性一个一个的赋值给我新new的对象不也行嘛?可以是可以,但是一来麻烦不说,二来,大家通过上面的源码都发现了clone是一个native方法,就是快啊,在底层实现的。
提个醒,我们常见的Objecta=newObject();Objectb;b=a;这种形式的代码复制的是引用,即对象在内存中的地址,a和b对象仍然指向了同一个对象。
而通过clone方法赋值的对象跟原来的对象时同时独立存在的。
java中的浅克隆和深克隆是什么
克隆是指克隆对象,在堆空间复制一块内存,是完全的两个对象,不是指针指向!浅克隆是指克隆一个对象,而该对象的属性只是基本数据类型,只克隆出该对象!深度克隆是指克隆的目标里面还有引用类型,引用类型里还有引用类型,同时把引用类型克隆出来叫深度克隆!常用的方法有两种,第一,需克隆的对象实现cloneable接口;第二,使用commons包提供的克隆方法。这两种方法都能实现深度克隆!
详细讲述Java中的克隆
经常听到有人说java中没有指针事实如此吗?no java是有指针的只不过换了个名字而已也就是我们经常提到的引用我们知道在java中一切都是对象那么我们如何操控对象?如何在成千上万的对象中找到我们所需的那个对象呢?又是如何让对象按照我们的意思来完成任务的呢?
Object o= new Object()
这是java中最常见的语句了在这句话中做了三件事首先声明一个Object类型的变量o在内存中为对象划分一块地址new Object()将声明的变量指向内存中的对象如此一来我们就可以通过o来操纵对象了就好像孩子们玩的遥控飞机在空中飞行的是飞机而使它做出优美动作的却是孩子们手中的摇控器
克隆是如今听到的较多的词汇听说已经将某只羊克隆了好几份了但愿这种技术不要在人身上实验 java中也有克隆与现实世界的克隆一样将一个实际存在的对象拷贝几份如下
//倒霉的羊public class Sheep implements Cloneable{private String name;public void setName(String arg){name= arg;}public String getName(){return name;}public Object clone() throws CloneNotSupportedException{return super clone();}}//克隆public class Main{public static void main(String[] args) throws CloneNotSupportedException{Sheep sheep= new Sheep();//先得到那只羊的实例sheep setName(我是真的);//给它做个记号System out println( sheep getName()=+ sheep getName());Sheep sheepClone=(Sheep)sheep clone();//开始克隆System out println( sheepClone getName()=+ sheepClone getName());}}
运行程序结果为
sheep getName()=我是真的
sheepClone getName()=我是真的
两只羊是一模一样的(哪怕那只羊瘸腿)让我们来看看代码首先要注意的是Sheep类实现了Cloneable接口(该接口属于java lang包默认已经导入了)该接口中并没有定义要实现的方法是个空接口起标志作用也就是说实现了这个接口的羊就不再是只普通的羊它是一只可以被克隆的羊再往下看有个clone方法返回Object类型的对象并抛出CloneNotSupportedException异常该方法覆写了父类(Object)的clone方法并在最后调用了super clone()这也意味着无论clone类继承结构是什么样的 super clone()都会直接或间接调用Object类的clone()方法看看jdk帮助文档会发现 Object类的clone()是一个native方法我们知道 native方法的效率一般来说都是远高于java中的非native方法这也说明了new一个对象然后将原对象中的数据导入到新创建的对象中去的做法是多么愚蠢必须说明的是Object中的clone方法是protected的所以要使用clone就必须继承Object类(默认)并且为了可以使其它类调用该方法必须将其作用域设置为public
以上只是一个简单clone的实现明天说说影子clone和深度clone
夜深了何为影子clone?先看一下例子
//倒霉的羊public class Sheep implements Cloneable{private String name;public void setName(String arg){name= arg;}public String getName(){return name;}public Object clone() throws CloneNotSupportedException{return super clone();}}//羊圈public class Sheepfold implements Cloneable{public Sheep sheep;public String name;public Sheepfold(){sheep= new Sheep();}public Object clone() throws CloneNotSupportedException{return super clone();}}//克隆public class Main{public static void main(String[] args) throws Exception{Sheepfold fold= new Sheepfold();fold name=小羊圈;fold sheep setName(小羊);Sheepfold fold=(Sheepfold)fold clone();System out println( fold name=+ fold name);System out println( fold sheep getName()=+ fold sheep getName());fold name=大羊圈;fold sheep setName(大羊);System out println(=====================================);System out println( fold name=+ fold name);System out println(* fold sheep getName()=+ fold sheep getName());System out println( fold name=+ fold name);System out println(* fold sheep getName()=+ fold sheep getName());System out println(=====================================);}}
在这个例子中有三个类 Sheep和Sheepflod都实现了Cloneable接口并且覆写了Object类的clone方法说明这两个类是具有克隆能力的注意一点在Sheepflod中持有一个Sheep的实例并在Main类中对其进行克隆结果如下
fold<fp class='fp-3p43k'></fp><fp class='fp-6kh1w'></fp>name=小羊圈fold<fp class='fp-3p43k'></fp><fp class='fp-szkq0'></fp>sheep<fp class='fp-6kh1w'></fp>getName()=小羊=====================================fold<fp class='fp-4kby3'></fp><fp class='fp-5w0yq'></fp>name=大羊圈* fold<fp class='fp-3p43k'></fp><fp class='fp-5w0yq'></fp>sheep<fp class='fp-y11o7'></fp>getName()=大羊fold<fp class='fp-5w0yq'></fp>name=小羊圈* fold<fp class='fp-y11o7'></fp>sheep<fp class='fp-5w0yq'></fp>getName()=大羊=====================================
请注意一下结果中带有*号的两条结果语句 fold sheep和fold sheep的name都变为了大羊很奇怪是吗?在此之前我们只对fold sheep的name赋过值为什么fold sheep的name也变为了大羊呢?原因很简单因为它们是指向同一个对象的不同引用从中可以看出调用Object类中clone()方法时首先在内存中划分一块同原对象相同的空间然后将原对象的内容原样拷贝至新对象我们知道 java中有基本数据类型对于基本数据类型这样的操作是没有问题的但对非基本类型变量它们保存的仅仅是对象的引用这也是为什么clone后非基本类型变量和原对象中的变量指向同一个对象的原因可能你已经注意到程序中用到了String类型即对象为什么没有出现引用指向同一地址的情况?这是因为String是一个不可更改的类(immutable class)每次给它赋值时都会产生一个新的String对象如 String str= a str+= b在这两句代码中当执行str+= b时实际上是重新成生了一个值为 ab的 String对象即重新分配了一块内存空间以上clone方法通常被称为影子clone影子clone给我们留下了一个问题即多个引用指向同一个对象如何解决该问题呢?答案为深度clone把上面的例子改成深度clone很简单只需将Sheepfold的clone()方法改为如下即可很简单只需将Sheepfold的clone()方法改为如下即可
public Object clone() throws CloneNotSupportedException{Sheepfold fold=(Sheepfold)super clone();sheep=(Sheep)fold sheep clone();return fold;}
lishixinzhi/Article/program/Java/gj/201311/27342OK,关于java深克隆方法是什么和java中的浅克隆和深克隆是什么的内容到此结束了,希望对大家有所帮助。