Cloneable Interface in java
2014-04-24 00:00
204 查看
一个类实现该接口表明该类的实例通过java.lang.Object#clone()方法拷贝字段的字段是合法的。
在一个没有实现该接口的实例上调用对象的clone方法会抛出CloneNotSupportedException异常。
通常,类实现该接口应该用public重写Object.clone方法(protected)。
注意,该接口没包含clone方法,因此,仅仅实现该接口是不可能克隆对象,即使通过反射调用克隆方法,也不能保证它会成功。
克隆一个对象是一个对象的不同标识和相同的内容,定义克隆,一个类必须实现Cloneable接口并且使用public重写对象的clone方法。此时,
克隆接口没有包含任何克隆方法,对象的clone方法是protected。
//没有实现该接口的实例上调用对象的clone方法会抛出CloneNotSupportedException异常
//如果类想允许客户端克隆它的实例,必须使用public修饰符重写对象的clone方法
怎样实现clone方法?
如果在一个non-final类中重写clone方法,你应该通过调用super.clone返回一个对象。
如果所有类的父类都服从这个规则,则调用super.clone将最终调用Object.clone方法,创建一个正确类的实例。
//若下面的类没有服从该规则
一旦从super.clone()中获得了对象,需要根据类的性质可能做一些修改
如果每个字段包含一个原始类型的值or引用一个不可变对象,不需要进一步处理。
如果引用了可变对象,为了克隆工作正常,它要求调用这些可变引用的clone方法。
//克隆可变引用
若有final字段指向可变的对象,为了是一个类可克隆,可能需要从一些字段中移除final修饰符(deep clone)。
如果实现一个线程安全可克隆类,注意它的clone方法必须正确同步就像任何其他方法一样。
实现clone方法非常棘手,避免实现它,寻找其他可代替方法
在一个没有实现该接口的实例上调用对象的clone方法会抛出CloneNotSupportedException异常。
通常,类实现该接口应该用public重写Object.clone方法(protected)。
注意,该接口没包含clone方法,因此,仅仅实现该接口是不可能克隆对象,即使通过反射调用克隆方法,也不能保证它会成功。
克隆一个对象是一个对象的不同标识和相同的内容,定义克隆,一个类必须实现Cloneable接口并且使用public重写对象的clone方法。此时,
克隆接口没有包含任何克隆方法,对象的clone方法是protected。
//没有实现该接口的实例上调用对象的clone方法会抛出CloneNotSupportedException异常
public class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } public static void main(String[] args) { Person p = new Person("Sam"); try { Person pClone = (Person)p.clone(); System.out.println(pClone.getName()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } }
//如果类想允许客户端克隆它的实例,必须使用public修饰符重写对象的clone方法
public class Person implements Cloneable { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } @Override public Person clone() { try { return (Person)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); throw new RuntimeException(); } } public static void main(String[] args) { Person p = new Person("Sam"); Person pClone = p.clone(); //如果clone不是public,不能调用 System.out.println(pClone.getName()); } }
怎样实现clone方法?
如果在一个non-final类中重写clone方法,你应该通过调用super.clone返回一个对象。
如果所有类的父类都服从这个规则,则调用super.clone将最终调用Object.clone方法,创建一个正确类的实例。
//若下面的类没有服从该规则
public class Animal implements Cloneable { private String name; public Animal(String name) { this.name = name; } public String getName() { return name; } public String bark() { return "This is how i bark, better care not"; } public Animal clone() { //当创建正确类的实例违法了调用super.clone() return new Animal(name); } } public class Dog extends Animal { public Dog(String name) { super(name); } public String bark() { return "Bow Bow!!"; } public Dog clone() { return (Dog)super.clone(); } } public class CloneableTest { public static void main(String[] args) { Dog dog = new Dog("Puppy"); Dog dogClone = dog.clone();//无法转换类型 System.out.println(dogClone.getName()); } } Exception in thread "main" java.lang.ClassCastException: Animal cannot be cast to Dog at Dog.clone(Dog.java:13) at CloneableTest.main(CloneableTest.java:6)
一旦从super.clone()中获得了对象,需要根据类的性质可能做一些修改
如果每个字段包含一个原始类型的值or引用一个不可变对象,不需要进一步处理。
如果引用了可变对象,为了克隆工作正常,它要求调用这些可变引用的clone方法。
//克隆可变引用
public class Person implements Cloneable { private String name; private Date dob; public Person(String name, Date dob) { this.name = name; this.dob = dob; } public String getName() { return name; } public Date getDob() { return dob; } @Override public Person clone() { Person p; try { p = (Person)super.clone(); p.dob = (Date) dob.clone(); return p; } catch (CloneNotSupportedException e) { e.printStackTrace(); throw new RuntimeException(); } } public static void main(String[] args) { Person p = new Person("Sam", new Date()); Person pClone = p.clone(); System.out.println(pClone.getName()); System.out.println(pClone.getDob()); System.out.println(pClone.getDob() == p.getDob()); } }
若有final字段指向可变的对象,为了是一个类可克隆,可能需要从一些字段中移除final修饰符(deep clone)。
如果实现一个线程安全可克隆类,注意它的clone方法必须正确同步就像任何其他方法一样。
实现clone方法非常棘手,避免实现它,寻找其他可代替方法
相关文章推荐
- clone() and the Cloneable Interface in Java
- Cloneable Interface in java
- Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨
- Java中Cloneable 和 clone()的总结和使用
- 五星-原型模式常使用于以下场景--而JAVA中的任何类只要实现了Cloneable标识接口,就可以使用clone方法来进行对象的拷贝
- ProbeException解决办法:There is no WRITEABLE property named 'id' in class 'java.lang.String'
- Java Cloneable和Serializeable
- java cloneable以及如何判断一个字符串是否为数字。
- a simple android user interface in java
- Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨
- Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface com.mysql.jdbc.Co
- java.lang.Cloneable
- java中Cloneable与Serializable接口
- Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨
- Java对象克隆(Clone)及Cloneable接口、Serializable接口的深入探讨
- Java中Serializable接口和Cloneable接口
- Exception in thread “main” java.lang.IncompatibleClassChangeError: Found interface org.apache.hadoop
- Why do many Collection classes in Java extend the abstract class and implement the interface as well
- java对象 深度克隆(不实现Cloneable接口)和浅度克隆
- java之实现Cloneable接口的详解,克隆一个对象--对应有浅克隆和深克隆,概念结合代码深入理解