通常在複製物件的時候,大多數直覺都是直接把一個物件 assign 給另外一個物件
譬如以下範例:
//....
Book book1 = new Book();
book1.setId(1);
book1.setBookName("Java Study");
/*以下複製一個新的Book物件*/
Book book2 = book1;
System.out.println("Id " + book2.getId() + "Name : " + book2.getName());
//....
以上程式用很直覺的方法複製了一個物件,之後book2 Console 出來的值,即會同 book1
如果要採用 Object 的 clone() 方法複製物件的話,需如以下指定的步驟
1.在欲被複製的類別中實作 Cloneable 介面
public class Book implements Cloneable{
//.....
}
2.在Book類別中實作 clone() 方法
public class Book implements Cloneable{
//....
public Object clone(){
try{
super.clone();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
}
}
3.需要複製時,讓 Book 物件呼叫 clone() 方法
Book book1 = new Book();
book1.setId(1);
book1.setBookName("Java Study");
Book book2 = book1.clone();
通常這個 clone 的作法不太常被使用,不過最近工作上去到一個問題就是
譬如:今天要將很多的 Book 物件放到到一個 List 中
但是有某個 Book 物它可能只是某個屬性不同,例如有10本書,他的其他屬性都一樣
只有書名不同,如果用很直覺的方式寫就如一開始那樣
Book book1 = new Book(); //第一本書
book1.setName("Java Study");
book1.setCategory("Tech");
list.add(book1); //加入 List
for(int i=0;i<9;i++){ //剩下的 9 本
Book tempBook = new Book();
tempBook = book1;
book1.setName(/*這裡取出書名*/);
list.add(tempBook);
}
說到這裡會發生一個問題,在 Java 的 List 中,當加入某個實體時 它會去比對加入 List 中的實體判斷是不是已經重複,如果已經重複 它就會進行類似更新的動作,
也就是 List 中還是會多出那一筆資料 但是之前的實體會被更新為目前加入的這個實體,
也就是說最後10筆資料都是一樣的 所以這就發生錯誤了!!
解決辦法中 你可以很簡單的就不要使用複製的作法,每筆資料就乾脆直接 New 一個實體 然後屬性直就慢慢設定上去,
雖然本例屬性不多,但是要是一個類別有超過50個屬性呢
所以如果這裡我們採用 Object 的 clone() 方法,就可以輕易解決這件事情
因為在 JAVA 執行 clone() 這個機制時,他是再記憶體外額外再新增一個實體 所以加入 List 之後會被當作是不同的實體物件,固程式稍改一下
Book book1 = new Book(); //第一本書
book1.setName("Java Study");
book1.setCategory("Tech");
list.add(book1); //加入 List
for(int i=0;i<9;i++){ //剩下的 9 本
Book tempBook = book1.clone(); //執行 clone 方法
book1.setName(/*這裡取出書名*/);
list.add(tempBook);
}
沒有留言:
張貼留言