Cloneable接口声明中没有指定要实现的方法,一个类要实现Cloneable,最好是覆盖Object类的clone()方法。
1. 如果类没有实现Cloneable接口,调用类对象的clone方法抛出CloneNotSupportedException。
- public class CloneableTest {
- public static void main(String[] args) throws CloneNotSupportedException {
- CloneableTest test = new CloneableTest();
- Object obj = test.clone();
- }
- }
结果是抛出CloneNotSupportedException异常
2. 我们无法定义一个类数组实现了Cloneable, 所以数组默认是实现了Cloneable接口。
- // Invalid definition
- public class Person[] implements Cloneable
- int[] iMarks = new int[] { 4, 7, 1 , 8 };
- int[] copyofiMarks = iMarks.clone();
运行没问题。
3. Object提供的clone方法是浅度复制 (shallow copy)。
- public class Name {
- private String firstName;
- private String lastName;
- // Omit the getters and setters as well as constructors
- }
- public class Person implements Cloneable {
- private Name name;
- private int age;
- // Omit the getters and setters as well as constructors
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- Name name = new Name("John", "Chen");
- Person person = new Person(name, 28);
- Person copyOfPerson = (Person)person.clone();
- name.setFirstName("Johnny");
- name.setLastName("Qin");
- person.setAge(29);
- System.out.println(copyOfPerson.getName().getFirstName() + " " +
- copyOfPerson.getName().getLastName() +
- " " + copyOfPerson.getAge());
结果是:Johnny Qin 28
对于原型类型(如int),clone是没问题的,被clone的对象改变了不会影响到复制品(age还是28)。
对于引用类型(如Name),clone方法只是复制了引用(浅度就体现在这),如果改变了引用的值,复制品也会受到影响(Johnny Qin)。
4. 继承链上的祖先必须要有一个类声明实现Cloneable接口。
- public class Person {
- }
- public class Male extends Person implements Cloneable {
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
- public class ChineseMale extends Male {
- }
- Person person = new Person();
- Male male = new male();
- ChineseMale chineseMale = new ChineseMale();
- person.clone();
- male.clone();
- chineseMale.clone();
person.clone()会报错。
5. Object类本身没有实现Cloneable接口,在一个Object类对象上调用clone方法会报CloneNotSupportedException。