java 对象的克隆(浅克隆和深克隆)

网友投稿 373 2023-04-26


java 对象的克隆(浅克隆和深克隆)

java 对象的克隆

一、对象的浅克隆

(1)需要克隆类需要重写Object类的clone方法,并且实现Cloneable接口(标识接口,无需实现任何方法)

(2)当需要克隆的对象中维护着另外一个引用对象,浅克隆不会克隆另外一个引用对下,而是直接复制维护的另外一个引用对象的地址。

(3)对象的浅克隆也不会调用到构造方法。

以下为对象的浅克隆的一个例子:

package com.clone;

import java.io.Serializable;

/**

* Description:

* 实现了Cloneable接口,并重写Object类的clone方法。

*

* @author lee

* */

public class CloneDemo1 implements Cloneable,Serializable{

//该克隆类封装的信息

public int id;

public String name;

public Address address;

/**

* Desciption:

* 默认构造器

*

* */

public CloneDemo1(){}

/**

* Description:

* 初始化id,name的构造器

*

* @param id id

* @param name 名字

* @param address 地址

* */

public CloneDemo1(int id, String name, Address address){

this.id=id;

this.name=name;

this.address = address;

}

/**

* Descriptin:

* 重写Object类的clone方法。

* if the object's class does not support the Cloneable interface.

* Subclasses that override the clone method can also throw this exception

* to indicate that an instance cannot be cloned.

*

* @throws CloneNotSupportedException

* */

@Override

public Object clone() throws CloneNotSupportedException{

return super.clone();

}

/**

* Description:

* 重写toString方法

*

* @return "id="+id+", name="+name

* */

@Override

public String toString(){

return "id="+id+", name="+name+", address:"+address.getAddress();

}

/**

* Description:

* 主方法

*

* */

public static void main(String[] args) throws CloneNotSupportedException{

CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));

//c2 复制了c1的地址,并没有复制整个c1对象

CloneDemo1 c2 = c1;

//c3 对象的浅克隆,复制了整个对象

CloneDemo1 c3 = (CloneDemo1)c1.clone();

//当对象c1改变其name或者id的时候,c2也会自动改变。

//因为c2只是复制了c1的地址,并非复制了c1的整个对http://象。

//相应的c3则不会随着c1改变而改变,意味着c3将c1整个对象克隆一份出来。

//当是,对象的浅克隆不会克隆被克隆对象当中的引用对象。

//因此c1改变其中的Address的引用对象时,c2,c3也会跟着改变。

c1.setName("cc");

c1.address.setAddress("上海");

System.out.println(c1+"\n"+c2+"\n"+c3);

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

/**

* Description:

* 一个封装着地址的类

*

* @author lee

* */

class Address implements Serializable{

public String address;

/**

* Description:

* 默认构造器

*

* */

public Address(){}

/**

* Description:

* 初试化address

*

* @param address 地址

* */

public Address(String address){

this.address = address;

}

//address的set和get方法

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

}

二、对象的深克隆

就是利用对象的输入输出流把对象写到文件上,再读取对象的信息,这就是对象的深克隆。

由于对象的浅克隆不会克隆被克隆对象其中的引用对象,而是直接复制其地址。因此,要克隆被克隆对象当中的引用类型则需要对象的深克隆。

而对象的深克隆使用的的对象序列化输入输出。

代码如下:

package com.clone;

imhttp://port java.io.FileInputStream;

imhttp://port java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

/**

* Description:

* 实现对象的深克隆

*

* @author lee

* */

public class CloneDemo2 {

/**

* Description:

* 将对象输出到一个文件当中。

*

* @param c 需要被写到文件当中的对象。

* */

public static void writeObject(CloneDemo1 c){

ObjectOutputStream out = null;

try{

//将对象输出在一个object.txt文件当中

out = new ObjectOutputStream(new FileOutputStream("./object.txt"));

out.writeObject(c);

}catch(IOException e){

System.out.println("写入对象的时候发生了错误。");

e.printStackTrace();

}finally{

//关闭资源

try{

out.close();

}catch(IOException e){

e.printStackTrace();

}

}

}

/**

* Description:

* 从文件中读取出一个对象来,并返回。

*

* @return c 返回一个对象。

* */

public static CloneDemo1 readObject(){

CloneDemo1 c = null;

ObjectInputStream input = null;

try{

//从object.txt文件中读取一个对象出来

input = new ObjectInputStream(new FileInputStream("./object.txt"));

c = (CloneDemo1)input.readObject();

}catch(IOException | ClassNotFoundException e){

e.printStackTrace();

System.out.println("读取对象的时候发生了错误。");

}finally{

//关闭资源

try{

input.close();

}catch(IOException e){

e.printStackTrace();

}

}

return c;

}

/**

* Description:

* 主方法

*

* @throws CloneNotSupportedException

* */

public static void main(String[] args) throws CloneNotSupportedException {

CloneDemo1 c1 = new CloneDemo1(1,"c1",new Address("北京"));

//c2 对象的浅克隆

CloneDemo1 c2 = (CloneDemo1)c1.clone();

//c3对象的深克隆

writeObject(c1);

CloneDemo1 c3 = readObject();

//因为对象的深克隆同时也克隆了被克隆对象维护的另外一个对象

//所以,当c1改变其当中的维护的另外一个对象的时候,c3不会随之改变。

//而c2位浅克隆,其维护的另外一个对象只是复制了c1维护的对象的地址,因此会随着c1的改变而改变。

c1.address.setAddress("上海");

System.out.println(c1+"\n"+c2+"\n"+c3);

}

}

对象的序列化,是需要实现Serializable接口的。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Vue学习笔记进阶篇之函数化组件解析
下一篇:Vue resource中的GET与POST请求的实例代码
相关文章

 发表评论

暂时没有评论,来抢沙发吧~