这篇文章主要介绍了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的整个对象。
//相应的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;
import java.io.fileinputstream;
import 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接口的。
以上就是java中关于对象的浅克隆以及深克隆详解的详细内容。