試圖深層復制合成對象時會遇到一個問題。必須假定成員對象中的clone()方法也能依次對自己的句柄進行深層復制,以此類推。這使我們的操作變得復雜。為了能正常實現深層復制,必須對所有類中的代碼進行控制,或者至少全面掌握深層復制中需要涉及的類,確保它們自己的深層復制能正確進行。
下面這個例子總結了面對一個合成對象進行深層復制時需要做哪些事情:
//: DeepCopy.java // Cloning a composed object class DepthReading implements Cloneable { private double depth; public DepthReading(double depth) { this.depth = depth; } public Object clone() { Object o = null; try { o = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } } class TemperatureReading implements Cloneable { private long time; private double temperature; public TemperatureReading(double temperature) { time = System.currentTimeMillis(); this.temperature = temperature; } public Object clone() { Object o = null; try { o = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } } class OceanReading implements Cloneable { private DepthReading depth; private TemperatureReading temperature; public OceanReading(double tdata, double ddata){ temperature = new TemperatureReading(tdata); depth = new DepthReading(ddata); } public Object clone() { OceanReading o = null; try { o = (OceanReading)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } // Must clone handles: o.depth = (DepthReading)o.depth.clone(); o.temperature = (TemperatureReading)o.temperature.clone(); return o; // Upcasts back to Object } } public class DeepCopy { public static void main(String[] args) { OceanReading reading = new OceanReading(33.9, 100.5); // Now clone it: OceanReading r = (OceanReading)reading.clone(); } } ///:~
DepthReading和TemperatureReading非常相似;它們都只包含了基本數據類型。所以clone()方法能夠非常簡單:調用super.clone()並返回結果即可。注意兩個類使用的clone()代碼是完全一致的。
OceanReading是由DepthReading和TemperatureReading對象合並而成的。為了對其進行深層復制,clone()必須同時克隆OceanReading內的句柄。為達到這個目標,super.clone()的結果必須造型成一個OceanReading對象(以便訪問depth和temperature句柄)。