2013-07-16 64 views
1

傢伙雖然這聽起來像它已經被問,但它不是一個問題。這裏創建的對象在Java中的副本W/O克隆,拷貝構造函數和拷貝工廠

問題很簡單,我想不使用克隆創建對象的精確拷貝,拷貝構造函數和拷貝工廠方法,因爲我們不能進行更改的類(無版權)。 假設我有一隻狗對象

我想創建一個更加狗對象,並在此重複我不得不改變一些屬性的值,但原來的對象不應該以任何方式會受到影響

感謝

+0

我想這隻能爲特定的類的對象來回答。 – Ingo

+1

你有私人領域,沒有getters/setters?在這種情況下,你將不得不使用反射,否則它非常簡單。 –

回答

1

您只需創建一個使用OldDog 你有沒有考慮過這樣的事情NewDog一個新的對象?

NewDog dog = new NewDog(someOldDogObject); 

雖然構造函數的NewDog可以。

public NewDog(OldDog oldDog){ 

this.dogWeight = oldDog.dogWeight; // keeping the same weight 
this.dogName = "newDog" + oldDog.dogName; // changing your dog name as per rquirement. 

} 
1

1)使用Apache的BeanUtils

Object cloned = BeanUtils.cloneBean(obj);//pass object for cloning 

2)使用反射

public <T> T clone(T obj1) { 
      try { 
       Class clazz = obj1.getClass(); 
       T obj2 = (T) clazz.newInstance(); 
       Field[] fields = clazz.getDeclaredFields(); 
       for (Field field : fields) { 
        try { 
         field.setAccessible(true); 
         int modifiers = field.getModifiers(); 
         if (!Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) { 
          field.set(obj2, field.get(obj1)); 
         } 
        } catch (IllegalArgumentException | IllegalAccessException ex) { 
         return null; 
        } 
       } 
       return obj2; 
      } catch (InstantiationException | IllegalAccessException ex) { 
       return null; 
      } 
     } 
0

您可以使用一個輔助類/方法:

MyObject cloneMyObject(MyObject o) { 
    MyObject cloned = new MyObject(); 
    cloned.fieldOne = o.fieldOne; 
    cloned.fieldTwo = o.fieldTwo; 
    // Or this depending on how MyObject was implemented 
    // cloned.setFieldOne(o.getFieldOne()); 
    // cloned.setFieldTwo(o.getFieldTwo()); 
    return cloned; 
} 

作爲一個側面說明,得到一個深層次的克隆對象確保所有引用類型在被添加到新對象之前被克隆。

+0

感謝這麼多的人就會嘗試實施所有這些,讓大家都知道這件事 – user1651070

0

您可以創建一個util的方法會爲你做到這一點,就這樣

public class MyDogUtils { 
    public Dog copy(final Dog res, final Dog dest) { 
     final Dog ret = (dest == null) ? new Dog() : dest; 
     ret.setName(res.getName()); 
      // some code here 
     return ret; 
     } 
    }