克隆
Object.clone() 访问修饰符为 protected ,如果某个类没有重写此方法,则这个类除被自己与子类能调用 clone() 方法外(实质上此时该类与子类访问的都是继承自 Object 的 clone() 方法),其他不管与这个类是在同一包还是不同包都是不可见的(这个好比:一个 B 类继承了 A 类, A 类在一个包中, B C在同另一包中,如果 A 中有一个 protected 方法没有在 B 中重写,则在C类中是不能调用的,即使现在 BC 为同包,因为实际上该方法属于 A 类,C与 A 是不同包不子类关系)。
集合类 ArrayList 重写了 clone 方法,但却是浅复制,在克隆集合类时,他不会循环去调用集合中对象的克隆方法,所以是浅拷贝,之所以这样设计,可能原因就是放在集合里的对象不一定都具有克隆的能力。所以如果想对 ArrayList 进行深层拷贝,以下操作是必须的:克隆了 ArrayList 之后,必须遍历 ArrayList 中的每个对象,逐一克隆。对 HashMap 做深层拷贝时,也必须做类似的操作。
Object.clone() 能够按对象大小创建足够的内存空间,从旧对象到新对象,复制所有的比特位。 这被称为逐位复制。但是, Object.clone() 在执行操作前,会先检查此类是否可克隆,即检查 它是否实现了 Cloneable 接口。如果没有实现此接口, Object.clone() 会抛出 CloneNotSuppo rtedException 异常,说明它不能被克隆。
使某类具有克隆能力要具备以下三点:
1 、类要实现 Cloneable 标志接口 , 即使重写了 clone 方法 , 如果类没有重写 Object 的 clone 方法时会抛出 CloneNotSupportedException 异常 ( 注:当然是要在调用 Object 的 clone 方法时才会抛出 )
2 、将自己的克隆方法申明成 public ,为了其他类可以克隆
3 、在重写的方法中调用父类克隆方法: super.clone()
java 常用 API 中重写了克隆的类有:
java.util.EnumMap.clone() java.util.EnumSet.clone()
java.util.ArrayList.clone() java.util.LinkedList.clone()
java.util.Vector.clone() java.util.HashMap.clone()
java.util.Hashtable.clone() java.util.TreeMap.clone()
java.util.IdentityHashMap.clone() java.util.TreeSet.clone()
java.util.HashSet.clone() java.util.Calendar.clone()
java.util.GregorianCalendar.clone() java.util.Date.clone()