java中的clone()方法的研究---(9)如何編寫正確的clone()方法:Collection
阿新 • • 發佈:2019-02-07
在自定義類Person中,會有Collection集合型別。
下面我就不一步步測試給大家看了,我就直接貼出來正確的clone方法了。
目前針對,ArrayList<String>, ArrayList<Integer>這兩個型別。
package tt.vo; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; public class Person implements Cloneable { // 基本資料型別 private int age; // Wrapper Class型別 private Integer height; // String 型別 private String name; // StringBuffer private StringBuffer address1; // StringBuilder private StringBuilder address2; // Date private Date date; // Timestamp private Timestamp timestamp; // int array private int[] intArray; // Integer Array private Integer[] integerArray; // String Array private String[] stringArray; private ArrayList<String> stringList; private ArrayList<Integer> integerList; @Override public Person clone() throws CloneNotSupportedException { Person p = (Person) super.clone(); // StringBuffer,StringBuilder 沒有實現clone方法 // 只能用 new, 去完成克隆動作 if (this.address1 != null) { p.address1 = new StringBuffer(this.address1); } if (this.address2 != null) { p.address2 = new StringBuilder(this.address2); } if (this.date != null) { p.date = (Date) this.date.clone(); } if (this.timestamp != null) { p.timestamp = (Timestamp) this.timestamp.clone(); } if (this.intArray != null) { p.intArray = this.intArray.clone(); } if (this.integerArray != null) { p.integerArray = this.integerArray.clone(); } if (this.stringArray != null) { p.stringArray = this.stringArray.clone(); } // list clone 要強轉型別, 此處是對list的淺克隆 if (this.stringList != null) { p.stringList = (ArrayList<String>) this.stringList.clone(); } if (this.integerList != null) { p.integerList = (ArrayList<Integer>) this.integerList.clone(); } return p; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Integer getHeight() { return height; } public void setHeight(Integer height) { this.height = height; } public String getName() { return name; } public void setName(String name) { this.name = name; } public StringBuffer getAddress1() { return address1; } public void setAddress1(StringBuffer address1) { this.address1 = address1; } public StringBuilder getAddress2() { return address2; } public void setAddress2(StringBuilder address2) { this.address2 = address2; } @Override public String toString() { return "Person [age=" + age + ", height=" + height + ", name=" + name + ", address1=" + address1 + ", address2=" + address2 + ", date=" + date + ", timestamp=" + timestamp + ", intArray=" + Arrays.toString(intArray) + ", integerArray=" + Arrays.toString(integerArray) + ", stringArray=" + Arrays.toString(stringArray) + ", stringList=" + stringList + ", integerList=" + integerList + "]"; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Timestamp getTimestamp() { return timestamp; } public void setTimestamp(Timestamp timestamp) { this.timestamp = timestamp; } public Integer[] getIntegerArray() { return integerArray; } public void setIntegerArray(Integer[] integerArray) { this.integerArray = integerArray; } public String[] getStringArray() { return stringArray; } public void setStringArray(String[] stringArray) { this.stringArray = stringArray; } public int[] getIntArray() { return intArray; } public void setIntArray(int[] intArray) { this.intArray = intArray; } public ArrayList<String> getStringList() { return stringList; } public void setStringList(ArrayList<String> stringList) { this.stringList = stringList; } public ArrayList<Integer> getIntegerList() { return integerList; } public void setIntegerList(ArrayList<Integer> integerList) { this.integerList = integerList; } }
---------------------------------------------------------------下面開始測試了------------------------------------------------------------------
測試類TestMain:
package tt; import java.util.ArrayList; import java.util.Arrays; import tt.vo.Person; public class TestMain { public static void main(String[] args) throws CloneNotSupportedException { // initialize Person p Person p = new Person(); // String List ArrayList<String> stringList = new ArrayList<String>(); stringList.addAll(Arrays.asList(new String("0"), new String("1"))); p.setStringList(stringList); // Integer List ArrayList<Integer> integerList = new ArrayList<Integer>(); integerList.addAll(Arrays.asList(new Integer("0"), new Integer("1"))); p.setIntegerList(integerList); System.out.println("p:" + p); Person pclone = p.clone(); System.out.println("pclone:" + pclone); System.out.println("-------------after set-------------------"); // string list String stringItem0 = p.getStringList().get(0); stringItem0 = "0000"; p.getStringList().add("111111"); // integer list Integer integerItem0 = p.getIntegerList().get(0) ; integerItem0 = 999; p.getIntegerList().add(88888); System.out.println("p:" + p); System.out.println("pclone:" + pclone); } }
debug截圖:
通過debug可以發現:
- p.integerList = (ArrayList<Integer>) this.integerList.clone(); 是淺克隆, 在淺克隆之後:
- p.integerList(id=25)與 pclone.integerList(id=34) id不同
- 我們要知道ArrayList內部維護的是Object [] elementData。
- p.integerList.elementData(id=36)和pclone.integerList.elementData(id=47) id不同
- 說白了,還是陣列的id不同(和我上一篇講陣列克隆情況一樣),雖然數組裡面的元素的id都相同,
- 但是在對p.integerList操作的時候(add,remove),是不會影響到pclone.integerList的
- 也因為是淺克隆:數組裡面的元素的id都相同。
- 注意,這裡要結合之前的帖子(Integer,String):
- 當從list取出Integer,String型別的變數之後,
- 你修改了stringItem0,integerItem0之後,是不會影響數組裡面所對應的元素的。
- 至於原因?看看http://blog.csdn.net/miqi770/article/details/45223191
- 對於p.stringList和p.integerList的現象是一樣的。