通常在複製物件的時候,大多數直覺都是直接把一個物件 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); }
沒有留言:
張貼留言