搜索
首页JavaJava面试题谈谈你对java中的深克隆和浅克隆的理解

谈谈你对java中的深克隆和浅克隆的理解

阿里面试官问题:

谈谈你对java中的深克隆和浅克隆的理解

回答:

(说明:本文针对深克隆和浅克隆的区别和实现方式?这一问题)

Talk is cheap#

最近不止一次遇见深浅克隆(深复制,浅复制)的问题,除了印象中有个clone方法外一脸懵逼!!!克隆(复制)在Java中是一种常见的操作,目的是快速获取一个对象副本。克隆分为深克隆和浅克隆。

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

总之深浅克隆都会在堆中新分配一块区域,区别在于对象属性引用的对象是否需要进行克隆(递归性的)。

Show you my picture#

pos:当前对象的地址;

son:son属性所指向的地址;

name:对象的name属性。

05c6b93772fd526dc5da6a57702a7c8.png

(相关推荐:java入门教程

Show you my code#

case1:

public class Son implements Serializable , Cloneable{    private String name;    private Son son;    public Son() {        super();
    }    public String getName() {        return name;
    }    public void setName(String name) {        this.name = name;
    }    public Son getSon() {        return son;
    }    public void setSon(Son son) {        this.son = son;
    }    @Override
    public String toString() {        return super.toString();
    }    @Override
    protected Object clone() throws CloneNotSupportedException {        return super.clone();
    }
}

测试

public static void main(String[] args) throws Exception{	// 创建父亲(LiLiu),儿子(LiWu),孙子(LiLiu)并关联
	Son father = new Son();
	father.setName("LiSi");
	Son son = new Son();
	son.setName("LiWu");
	Son grandSon = new Son();
	grandSon.setName("LiLiu");
	father.setSon(son);
	son.setSon(grandSon);	// 调用clone方法
	Son fatherCopy =  (Son) father.clone();	boolean flag1 = fatherCopy==father;	boolean flag2 = fatherCopy.getSon() == son;	boolean flag3 = fatherCopy.getSon().getSon() == grandSon;	// 比较克隆后的地址
	System.out.println(flag1);// false
	System.out.println(flag2);// true
	System.out.println(flag3);// true
	// 比较Name
	flag1= fatherCopy.getName()==father.getName();
	flag2 = fatherCopy.getSon().getName() == son.getName();
	flag3 = fatherCopy.getSon().getSon().getName() == grandSon.getName();
	System.out.println(flag1);// true
	System.out.println(flag2);// true
	System.out.println(flag3);// true
	
	//将对象写到流里    
	ByteArrayOutputStream byteOut=new ByteArrayOutputStream();    
	ObjectOutputStream objOut=new ObjectOutputStream(byteOut);    
	objOut.writeObject(father);	//从流里读出来    
	ByteArrayInputStream byteIn=new ByteArrayInputStream(byteOut.toByteArray());    
	ObjectInputStream objInput=new ObjectInputStream(byteIn);
    fatherCopy = (Son) objInput.readObject();
	flag1= fatherCopy==father;
	flag2 = fatherCopy.getSon() == son;
	flag3 = fatherCopy.getSon().getSon() == grandSon;
	System.out.println(flag1);// false
	System.out.println(flag2);// false
	System.out.println(flag3);// false
	
	// 比较Name
	flag1= fatherCopy.getName()==father.getName();
	flag2 = fatherCopy.getSon().getName() == son.getName();
	flag3 = fatherCopy.getSon().getSon().getName() == grandSon.getName();
	System.out.println(flag1);// false
	System.out.println(flag2);// false
	System.out.println(flag3);// false}

从上文代码及运行结果不难看出,如果对象实现Cloneable并重写clone方法不进行任何操作时,调用clone是进行的浅克隆。而使用对象流将对象写入流然后再读出是进行的深克隆。

思考:既然实现Cloneable接口并重写clone接口只能进行浅克隆。但是如果类的引用类型属性(以及属性的引用类型属性)都进行浅克隆,直到没有引用类型属性或者引用类型属性为null时,整体上就形成了深克隆。既对象的引用类型属性和属性的应用类型属性都实现Coloneable,重写clone方法并在clone方法中进行调用。

protected Object clone() throws CloneNotSupportedException {
      Son result = (Son) super.clone();	if (son != null) {
		result.son = (Son) son.clone();
	}    return result;
}

个人认为,在选择深克隆方法时,应根据对象的复杂程度,如引用类型属性是否有多层引用类型属性关系。如果对象只有一层或者两层引用类型的属性,选择思考中所提到的方法较为方便,反之则使用对象流。

更多相关面试题请访问:java面试题及答案

以上是谈谈你对java中的深克隆和浅克隆的理解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:博客园。如有侵权,请联系admin@php.cn删除

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境