Object.clone()
肯定是做了一些在Java中無法實現的東西。
從Josh Bloch on Design: Copy Constructor versus Cloning(重點煤礦):
對象的克隆方法是非常棘手的。它基於現場副本,它是「超語言」。它不調用構造函數就創建一個對象。不保證它保留了構造函數建立的不變量。
Object.clone()
做的事情不應該被語言所允許。這就是爲什麼在其他原因中,clone()
被打破。
(如果你還沒有準備好,你應該也看過他的書有效的Java,理解爲什麼他(和其他許多人)認爲Java的clone()
和Cloneable
被打破)。
如果你只是想創建同一個類的對象作爲另一個任意對象,那麼這還算是可以實現的,有一些需要注意的(即不是所有的類型都公開實例化)通過使用反射。
這裏有一個如何使用反射來一個例子:
- 找出類對象的類型在運行時
- 列出其聲明的字段,方法和構造
- 找到它的拷貝構造函數(如果有),並嘗試使用給定對象作爲 參數調用它。
import java.lang.reflect.*;
public class NewInstance {
static void print(String label, Object[] arr) {
System.out.println(label);
for (Object o : arr) {
System.out.println(o);
}
System.out.println("---");
}
static Object newInstance(Object o) {
Class<?> c = o.getClass();
System.out.println("Class is " + c);
print("FIELDS:", c.getDeclaredFields());
print("METHODS:", c.getDeclaredMethods());
print("CONSTRUCTORS:", c.getDeclaredConstructors());
try {
Constructor<?> cc = c.getDeclaredConstructor(c);
o = cc.newInstance(o);
} catch (NoSuchMethodException e) {
System.out.println("No copy constructor found!");
} catch (IllegalAccessException e) {
System.out.println("Copy constructor inaccessible!");
} catch (InstantiationException e) {
System.out.println("Instantiation failed!");
} catch (InvocationTargetException e) {
System.out.println("Copy constructor threw " + e.getCause());
}
return o;
}
public static void main(String args[]) {
Object o1 = "hello";
Object o2 = newInstance(o1);
boolean success = (o1 != o2) && (o1.equals(o2));
System.out.println("Attempt " + (success ? "succeeded!" : "failed :("));
}
}
輸出:
Class is class java.lang.String
FIELDS:
// (omitted)
METHODS:
// (omitted)
CONSTRUCTORS:
public java.lang.String()
public java.lang.String(java.lang.String) // this is what we're looking for!
// (rest omitted)
---
Attempt succeeded!
請注意,這只是爲了顯示類型的例子可以在運行時間和拷貝構造函數可以尋找和調用進行檢查。原因是,如果o
是ArrayList
,則它不起作用,因爲它沒有構造函數,其取值爲ArrayList
(它的確有一個取值爲Collection
,其值爲ArrayList
)。
我會把它留給你作爲練習如何擴大複製構造函數的搜索以包含這些兼容的重載。
你想達到什麼目的。如果它只是代碼,請將其明確寫出。 – 2010-03-25 18:31:55
這段代碼甚至沒有編譯,也沒有任何意義。檢查Savvas Dalkitsis的答案。你需要澄清一下你究竟想達到什麼目的。 – BalusC 2010-03-25 18:48:55
現在應該更有意義了.. – 2010-03-25 18:55:51