java中的clon()和cloneable接口浅析(转)

今天看了一上午关于clone()和cloneable interface 的文章,我推荐一篇供你们参考学习。 php

蓝色为个人翻译,有不当之处,你们多多包涵! app

 

clone() and the Cloneable Interface in Java ide

 

 

......The clone( ) method generates a duplicate copy of the object on which it is called. Only classes that implement the Cloneable interface can be cloned. post

 


...clone()产生了一个调用它的对象的复制;只有实现了Cloneable接口的类才能够被复制。学习

 

 

 


The Cloneable interface defines no members. It is used to indicate that a class allows a bitwise copy of an object (that is, a clone ) to be made. If you try to call clone( ) on a class that does not implement Cloneable , a CloneNotSupportedException is thrown. When a clone is made, the constructor for the object being cloned is not called. A clone is simply an exact copy of the original. this

 


Cloneable 接口没有定义任何成员。它用来指明一个类能够逐位复制一个对象。若是你试图对一个没有实现cloneable接口的类调用clone()方法,一个CloneNotSupportedException 就会抛出。在复制时,被复制的对象的构造器并无被调用。复制对象就是原来对象的拷贝。 翻译

 


Cloning is a potentially dangerous action, because it can cause unintended side effects. For example, if the object being cloned contains a reference variable called obRef, then when the clone is made, obRef in the clone will refer to the same object as does obRef in the original. If the clone makes a change to the contents of the object referred to by obRef, then it will be changed for the original object, too. Here is another example. If an object opens an I/O stream and is then cloned, two objects will be capable of operating on the same stream. Further, if one of these objects closes the stream, the other object might still attempt to write to it, causing an error. code

 

复制是一种存在潜在危险的行为,由于它会引发一些意想不到的负做用。例如,若是被复制的对象包含一个名为 obRef 引用变量,在复制时,复制对象的 obRe和f 原来对象的 obRef 都会指向同一个对象。若是复制对象对 obRef 指向的对象的内容作出一些改变,对于原来对象来讲,也就至关于它也被改变了。还有另外一个例子,若是一个操做I/O流的对象被复制了,这两个对象都能对同一I/O流进行操做。进一步说,若是它们两个中的一个关闭了I/O流,而另外一个对象可能试图对I/O流进行写操做,这就会引发错误。 对象

 

 

Because cloning can cause problems, clone( ) is declared as protected inside Object . This means that it must either be called from within a method defined by the class that implements Cloneable , or it must be explicitly overridden by that class so that it is public. Let's look at an example of each approach. 接口

由于复制能够引发许多问题,clone()在object类中被声明为protected.这意味着,它要么在一个实现了cloneable接口的类中的某一方法里被调用,要么在明确的在那个类中的被重写,且被声明为public的。下面,咱们来看一下每一种方法。

 

 

 


The following program implements Cloneable and defines the method cloneTest( ) , which calls clone( ) in Object :

// Demonstrate the clone() method.
class TestClone implements Cloneable {
int a;
double b;
// This method calls Object's clone().
TestClone cloneTest() {
try {
// call clone in Object.
return (TestClone) super.clone();
} catch(CloneNotSupportedException e) {
System.out.println("Cloning not allowed.");
return this;
}
}
}

class CloneDemo {
public static void main(String args[]) {
TestClone x1 = new TestClone();
TestClone x2;
x1.a = 10;
x1.b = 20.98;
x2 = x1.cloneTest(); // clone x1
System.out.println("x1: " + x1.a + " " + x1.b);
System.out.println("x2: " + x2.a + " " + x2.b);
}
}

Here, the method cloneTest( ) calls clone( ) in Object and returns the result. Notice that the object returned by clone( ) must be cast into its appropriate type (TestClone ). The following example overrides clone( ) so that it can be called from code outside of its class. To do this, its access specifier must be public , as shown here:

// Override the clone() method.
class TestClone implements Cloneable {
int a;
double b;
// clone() is now overridden and is public.
public Object clone() {
try {
// call clone in Object.
return super.clone();
} catch(CloneNotSupportedException e) {
System.out.println("Cloning not allowed.");
return this;
}
}
}

class CloneDemo2 {
public static void main(String args[]) {
TestClone x1 = new TestClone();
TestClone x2;
x1.a = 10;
x1.b = 20.98;
// here, clone() is called directly.
x2 = (TestClone) x1.clone();
System.out.println("x1: " + x1.a + " " + x1.b);
System.out.println("x2: " + x2.a + " " + x2.b);
}
}

The side effects caused by cloning are sometimes difficult to see at first. It is easy to think that a class is safe for cloning when it actually is not. In general, you should not implement Cloneable for any class without good reason.

 

以上两个程序,运行一下,便于理解。

 

如下在补充两点:

1  It is what is known as a 'marker' interface . A marker interface has no methods or fields and serves only to identify the semantics of that interface. Another example is Serializable .

2  object.clone()可能产生a shallow copy()也可能产生a deep copy.

 

参考:http://www.codeguru.com/forum/showthread.php?s=&postid=660398#post660398

相关文章
相关标签/搜索