使用克隆可以快速为我们构建一个已有对象的副本
浅克隆(Shadow Clone)
把原型对象中成员变量为值类型的属性都复制给克隆对象
把原型对象中成员变量为引用类型的引用地址也复制给克隆对象
如果原型对象中有引用类型,则仅仅复制引用对象的地址,共享引用对象
深克隆(Deep Clone)
将原型对象中所有类型
无论是值类型还是引用类型,都复制一份给克隆对象
也就是深克隆会把原型对象所引用的对象也复制一份
实现克隆首先要实现Cloneable接口,以及重写Object中的clone方法
一、常见面试题
在java.lang.Object中对clone()方法的约定有哪些?
对于所有对象来说,x.clone()!=x应该返回true,因为克隆对象和原型对象不是一个对象
对于所有对象来说,x.clone().getClass==x.getClass()应该返回true,因为类型是一样的
对于所有对象来说,x.clone().equals(x)应该返回true,因为复制的时候值都相等
Arrays.copyOf()是深克隆还是浅克隆?
深克隆,是new了一个数组之后System.arraycopy
深克隆的实现方式有哪些?
所有对象都实现克隆方法
通过构造方法实现深克隆
使用JDK自带的字节流实现深克隆
使用第三方工具类实现深克隆,比如Apache Commons Lang
使用Json工具实现深克隆,比如Gson、FastJSON
Java中的克隆为什么要设计成既要实现接口,又要重写方法?
实现接口的猜想:
设计理念猜想:
如果为每一个类都实现克隆方法,显然不合适,那如何标记一个类能克隆?
在类上新增标识,此标识用于声明某个类拥有克隆功能,类似于final
为了一个重要但不常用的克隆功能新增关键字显然不合适
使用java中的注解
克隆出现的比较早(JDK1.0),比注解早,所以不现实
实现某个接口
继承某个类
java是单继承的,如果为了一个克隆功能继承,显然比较鸡肋
为什么要在object中添加clone方法:
clone方法的语义很特殊,最好能有jvm支持,既然要jvm支持,最好在某个api中暴露出来。最直接的办法就是放在Object中,因为Object是所有类的父类,所以很方便就能够调用到了。