基本介绍
类实现接口 Cloneable 以向 Object.clone() 方法指示该方法创建该类实例的逐字段副本是合法的。
在未实现接口的 Cloneable 实例上调用 Object 的克隆方法会导致引发异常 CloneNotSupportedException 。
按照约定,实现此接口的类应使用公共方法重写 Object.clone (受保护)。有关重写此方法的详细信息,请参阅 Object.clone() 。
请注意,此接口不包含该 clone 方法。因此,不能仅仅因为它实现了这个接口而克隆一个对象。即使以反射方式调用克隆方法,也不能保证它会成功。
说人话:要克隆就得实现这个接口还得重写clone方法,克隆就是将一份数据创造一份完全一样的数据拷贝
基本使用
源码分析
克隆方法在底层源码中首先是先去其父类找clone方法,但他的父类abstractlist并没有实现clone方法,所以继续往上找,找到了object的clone方法,但是他的clone方法是用c实现的,咱看不到,跳过。
接下来就是copyof方法,将elementdata和size丢进去,其实就是数组中的元素和数组长度。方法首先判断该类是不是object或者其子类,是的话就创建一个object数组,不是就用new instance创建一个新数组,然后就用arraycopy(一样是个咱看不到的操作)将数组放到新生成的数组中,然后返回copy对象。
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
浅拷贝
局限性:该对象的属性若是还有对象,进行拷贝,其对象还是原来的对象,意思就是属性中的对象进行修改,拷贝前后的数据都会变动,因此可能造成循环依赖。
深拷贝
对需要拷贝的对象的clone方法进行修改,clone出本体,还要让属性中的对象也调用clone方法并赋值给本体,有几个对象就clone几次赋值几次。