标签:style http io color ar os 使用 sp java
原文地址:http://leihuang.net/2014/11/14/java-clone/
In java, it essentially means the ability to create an object with similar state as the original object.
字典中的意思就是复制(强调跟原来的一模一样)。
*By default, java cloning is ‘field by field copy’ *.因为Object类不知道具体类的结构,无法确定哪个clone方法将被调用。所以JVM规定clone,做如下操作。
翻译的不好,%>_<%
除了上面两条默认的操作之外,你也可以重载clone方法,制定一套自己的clone方法。
每种支持clone的语言都有它自己的规则,java也不例外。java中如果一个类需要支持clone的话,必须要做如下事情:
/*
Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object.
The general intent is that, for any object x, the expression:
1) x.clone() != x will be true
2) x.clone().getClass() == x.getClass() will be true, but these are not absolute requirements.
3) x.clone().equals(x) will be true, this is not an absolute requirement.
*/
protected native Object [More ...] clone() throws CloneNotSupportedException;
下面我们通过例子来分析:
class Father implements Cloneable{
private int age ;
private String name ;
private Son son ;
public Father(int age,String name,Son son){
this.age = age ;
this.name = name ;
this.son = son ;
}
public Son getSon(){
return this.son ;
}
@Override
protected Object clone()throws CloneNotSupportedException{
return super.clone() ;
}
}
class Son{
private int age ;
private String name ;
public Son(int age ,String name){
this.age = age ;
this.name = name ;
}
public void setName(String name){
this.name = name ;
}
public String getName(){
return this.name ;
}
}
public class CloneDemo {
public static void main(String args[]) throws CloneNotSupportedException{
Son s = new Son(10,"Jack") ;
Father fa = new Father(40,"Tom",s) ;
Father clonedFa = (Father) fa.clone() ;
System.out.println(fa!=clonedFa);
System.out.println(clonedFa.getClass()==fa.getClass());
System.out.println(clonedFa.equals(fa));
//now we change the fa‘s son name by the clonedFa‘s son name
clonedFa.getSon().setName("Jay");
System.out.println(fa.getSon().getName());
}
}
/*print:
true
true
false
Jay
*/
上面的代码中可以看出,原始的和克隆的Father类对象,拥有指向同一对象的两个引用,所以可以通过改变clonedFa中的Son来改变fa中Son对象。这就时所谓的浅拷贝.下面我们详细讨论一下浅拷贝和深拷贝。
这是java中默认的实现。上面的例子中就是浅拷贝。不创建一个新的克隆拷贝对象Son,而是直接两个引用指向同一对象。
If we want a clone which is independent of original and making changes in clone should not affect original.you can try Deep Cloning.
we change the clone() method in the Father class .
@Override
protected Object clone() throws CloneNotSupportedException {
Father fa = (Father)super.clone();
fa.setSon((Son)fa.getSon().clone());
return fa;
}
and we need Override the clone() method in the Son class. like this.
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
现在我们已经实现深拷贝了。
拷贝构造函数时一种特殊的构造器,它讲自己的类类型作为参数。我们传递一个类的实例给拷贝构造函数,然后它将返回一个新的类实例。lets see this in example
public class PointOne {
private Integer x;
private Integer y;
public PointOne(PointOne point){
this.x = point.x;
this.y = point.y;
}
}
如果要继承它的话,则需要复制子类的参数,和传递参数给父类的构造器。如下:
public class PointTwo extends PointOne{
private Integer z;
public PointTwo(PointTwo point){
super(point); //Call Super class constructor here
this.z = point.z;
}
}
下面是测试代码:
class Test
{
public static void main(String[] args)
{
PointOne one = new PointOne(1,2);
PointTwo two = new PointTwo(1,2,3);
PointOne clone1 = new PointOne(one);
PointOne clone2 = new PointOne(two);
//Let check for class types
System.out.println(clone1.getClass());
System.out.println(clone2.getClass());
}
}
Output:
class corejava.cloning.PointOne
class corejava.cloning.PointOne
你也可以使用静态工厂的方法来实现它。
public class PointOne {
private Integer x;
private Integer y;
public PointOne(Integer x, Integer y)
{
this.x = x;
this.y = y;
}
public PointOne copyPoint(PointOne point) throws CloneNotSupportedException
{
if(!(point instanceof Cloneable))
{
throw new CloneNotSupportedException("Invalid cloning");
}
//Can do multiple other things here
return new PointOne(point.x, point.y);
}
}
这是例外一种深拷贝的方法。这里就不多讲了,详细见:A mini guide for implementing serializable interface in java
1) When you don’t know whether you can call the clone() method of a particular class as you are not sure if it is implemented in that class, you can check with checking if the class is instance of “Cloneable” interface as below.
if(obj1 instanceof Cloneable){
obj2 = obj1.clone();
}
//Dont do this. Cloneabe dont have any methods
obj2 = (Cloneable)obj1.clone();
2) No constructor is called on the object being cloned. As a result, it is your responsibility, to make sure all the members have been properly set. Also, if you are keeping track of number of objects in system by counting the invocation of constructors, you got a new additional place to increment the counter.
Reference:
2014-11-14 15:48:12
Brave,Happy,Thanksgiving !
标签:style http io color ar os 使用 sp java
原文地址:http://blog.csdn.net/speedme/article/details/41145155