有沒有人有任何建議或建立的最佳做法和命名約定在Java複製構造函數/工廠方法等?特別是說,我有一個類Thing
,我想要一個方法返回一個新的Thing
與傳入的Thing
相同的值(或作爲實例,如果它是一個實例方法)。你會有這個作爲構造函數或靜態工廠方法或實例方法嗎?你會怎麼稱呼它?如果你不用Java進行克隆,那麼你做什麼,你叫什麼?
根據標題,我想避免clone()
和Cloneable
。
有沒有人有任何建議或建立的最佳做法和命名約定在Java複製構造函數/工廠方法等?特別是說,我有一個類Thing
,我想要一個方法返回一個新的Thing
與傳入的Thing
相同的值(或作爲實例,如果它是一個實例方法)。你會有這個作爲構造函數或靜態工廠方法或實例方法嗎?你會怎麼稱呼它?如果你不用Java進行克隆,那麼你做什麼,你叫什麼?
根據標題,我想避免clone()
和Cloneable
。
如果需要,您可以覆蓋clone()-方法。另一個慣用的做法是構造函數,它需要這種類型的對象,即new ArrayList(anotherList)。
我會稱之爲複製方法或複製構造函數(視情況而定)。如果這是一種靜態方法,那麼我會稱之爲工廠。
在做什麼方面,最靈活和最長壽的選項是複製構造函數。這使得子類能夠像父母一樣複製自己。
我會做一個構造
...
public Thing(Thing copyFrom)
{
attr1 = copyFrom.attr1;
attr2 = copyFrom.attr2;
//etc...
}
那麼當你想克隆它
Thing copy = new Thing(copy from me);
你有幾個選擇,實施Cloneable
,添加一個拷貝構造函數,但我的首選方式是使用一個名稱描述複製操作正在進行的方法(靜態還是實例) - 是深層還是淺層複製等。
有效的Java推薦門茲以下任一操作:
一個拷貝構造函數(如由他人注意):
公共項目(項目項)
副本工廠方法:
公共靜態項目newInstance(Item item)
(另外,不可複製的不可變項)
主要區別在於#1選擇結果的實際類,#2實現者可以返回子類。這門課的語義可以指導你將哪一門課最好。
使用immutable data structures。你覺得你需要clone()
的唯一原因是你正在改變你的對象。別那樣做。想想你可以如何:
例如,這裏有一個「二傳手」的一個不變的三維矢量對象:
public Vector3D setX(double x) {
return new Vector3D(x, this.y, this.z);
}
所以我想我說的是我對使用拷貝構造函數,而不是突變,和我只是根據我想修改的屬性命名它們。
另一種選擇是實現在源對象的複製方法,例如:
interface Has3DCoords {
void setLocation(double x, double y, double z);
void copyCoordsTo(Has3DCoords dest);
}
你會然後實現複印用一塊代碼等:
class Thing implements Has3DCoords {
private Point3D loc;
// ...
void setLocation(double x, double y, double z) {
loc.setLocation(x, y, z);
// or: loc = new Point3D(x, y, z);
}
void copyCoordsTo(Has3DCoords dest) {
loc.copyCoordsTo(dest);
// or: dest.setLocation(loc.getX(), loc.getY(), loc.getZ());
}
OtherThing createOtherThing() {
OtherThing result = new OtherThing();
this.copyCoordsTo(result);
return result;
}
}
這可以是有用如果:
loc
爲Thing
這不是複製對象的最好方法,但如果你希望一個序列化對象的執行深拷貝以下有時是有用的。這避免了必須編寫複製構造函數,實現Cloneable或編寫工廠類。
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
//Serializes the input object
oos.writeObject(input);
ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
//Copy of the input object
Object output = ois.readObject();
不要忘記處理異常並很好地關閉流。
爲什麼你想避免的clone()和Cloneable的? – 2009-07-06 15:15:59