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

相關文章
相關標籤/搜索