【码农每日一题】Java clone (Part 1)相关面试题

224 阅读3分钟

关注一下嘛,又不让你背锅!

问:为什么需要克隆?

答:因为在编程中会遇到一种情况,有一个 DemoBean 的对象实例 demo1 在某一时刻已经包含了一些有效值,此时可能会需要一个和 demo1 完全相同的新对象 demo2 且此后对 demo1 的任何改动都不影响到 demo1 中的值,在 Java 中用简单的赋值语句是不能满足这种需求的,所以我们需要使用其他的途径来保证 demo1 与 demo2 是两个独立的对象且 demo2 的初始值是由 demo1 对象确定的,而克隆就是其官方提供的一种接口定义(至少比主动 new 对象然后取值赋值方便)。

问:浅度克隆(浅拷贝)和深度克隆(深拷贝)的区别是什么?

答:

浅度克隆:被复制对象(一个新的对象实例)的所有变量都含有与原来的对象相同的值,对于基本数据类型的属性复制一份给新产生的对象,对于非基本数据类型的属性仅仅复制一份引用给新产生的对象(新实例中引用类型属性还是指向原来对象引用类型属性)。

深度克隆:被复制对象(一个新的对象实例)的所有变量都含有与原来的对象相同的值,而那些引用其他对象的变量将指向被复制过的新对象(新内存空间),而不再是原有的那些被引用的对象,换言之深度克隆把要复制的对象所引用的对象都复制了一遍,也就是在浅度克隆的基础上,对于要克隆的对象中的非基本数据类型的属性对应的类也实现克隆,这样对于非基本数据类型的属性复制的不是一份引用。

问:String 克隆的特殊性在哪里?StringBuffer 和 StringBuilder 呢?

答:由于基本数据类型都能自动实现深度 clone,引用类型默认实现的是浅度 clone,而 String 是引用类型的一个特例,我们可以和操作基本数据类型一样认为其实现了深度 clone(实质是浅克隆,切记只是一个假象),由于 String 是不可变类,对于 String 类中的很多修改操作都是通过新 new 对象复制处理的,所以当我们修改 clone 前后对象里面 String 属性的值时其实都是属性引用的重新指向操作,自然对 clone 前后对象里 String 属性是没有相互影响的,类似于深度克隆;所以虽然他是引用类型而且我们在深度克隆时无法调用其 clone 方法,但是其不影响我们深度克隆的使用。

如果要实现深度克隆则 StringBuffer 和 StringBuilder 是需要主动特殊处理的,否则就是真正的对象浅克隆,所以处理的办法就是在类的 clone 方法中对 StringBuffer 或者 StringBuilder 属性进行如下主动拷贝操作。

再次强调,这个区别非常重要,即便不是面试题自己开发中也要注意这个坑。

戛然而止!这是 clone 基础概念面试题,踩坑题敬请期待明日推送~~

老铁,别嫌短,长了你肯定不会看完的,所以这就是码农每日一题的宗旨~

看完分享一波朋友圈嘛,小编也是下班后花很多心血来运营的,和你的小伙伴一起讨论才更加有意思~

看个笑话放松一下

一个程序员在海滨游泳时溺水身亡。他死前拼命的呼救,当时海滩上有许多救生员,但是没有人救他。因为他一直大喊“F1!”“F1!”,谁都不知道“F1”究竟是什么意思。

You laugh at me for being different, but I laugh at you for being the same. 

你嘲笑我和别人不一样,我嘲笑你和大家都一样。