2015-06-21 24 views
5

我想克隆給定的對象。我如何說服編譯器的對象是可複製的(java)?

如果我這樣做

public class Something{ 
    Object o; //set in the constructor 
    public Something(Object o){ 
     this.o = o;} 
    public Something clone() throws CloneNotSupportedException{ 
     Something temp = super.clone(); 
     if (o instanceof Cloneable) //important part 
      temp.o = o.clone(); //important part 
     else temp.o = o; 
    } 
} 

這不會監守o.clone工作()是受保護的。

如果我這樣做,而不是

  if (o instanceof Cloneable) //important part 
      temp.o = ((Cloneable)o).clone(); //important part 

它不會工作,要麼因爲Cloneable的是一個空的接口。

那麼我如何說服編譯器可以克隆o?

+0

@immibis,我不認爲你的評論增加了很多值得坦白的。 – aioobe

+2

你必須讓你的類實現'Cloneable'並實現'clone'方法。 – Rishav

+1

來自doc:「一個類實現了Cloneable接口,以向Object.clone()方法表明,該方法爲該類的實例的字段 - 場複本創建是合法的。」 – Rishav

回答

2

你不能在執行clone()時必須知道什麼是克隆,必須知道實現類。

克隆的替代方法是使用copy-constructor,它具有相同的問題,您必須知道該類。

有人說,不使用克隆,有人說定義自己的接口,例如:Copyablehttp://c2.com/cgi/wiki?CloneableDoesNotImplementClone

-1

java.lang.Cloneable接口必須由我們要創建對象克隆的類來實現。如果我們沒有實現Cloneable接口,clone()方法會生成CloneNotSupportedException

clone()方法在Object類中定義。該clone()方法的語法如下:

protected Object clone() throws CloneNotSupportedException 

所以,你的類應該是作爲

public class Something implements Cloneable { 

    private Object o; //set in the constructor 

    public Something(Object o) { 
     this.o = o; 
    } 

    @Override 
    public Object clone() throws CloneNotSupportedException { 
     return super.clone(); 
    } 

    public Object getObject() { 
     return o; 
    } 

    public static void main(String[] args) { 
     Something s = new Something("try"); 
     System.out.println(s.getObject()); 
     try { 
      Something s2 = (Something) s.clone(); 
      System.out.println(s2.getObject()); 
     } catch (CloneNotSupportedException ex) { 
      Logger.getLogger(Something.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 
+0

問題是如何克隆'o'。 – immibis

1

您可以反射

//We need reflection 
import java.lang.reflect.*; 
    //This class is the backbone of the feature 
    public class MyCloneable implements Cloneable { 

     //A constructor. For the sake of simplicity, the constructor is an empty constructor. 
     public MyCloneable() {} 

     //We implement the clone method. This returns a clone 
     protected Object clone() throws CloneNotSupportedException { 
      //We need the class of the object 
      class c = this.getClass(); 
      //We get the empty constructor of the object 
      Constructor constructor = c.getConstructor(new Class[]{}); 
      //newClone will be the cloned object 
      Object newClone = constructor.newInstance(new Object[]{}); 
      //We get the array of fields 
      Field[] fields = c.getDeclaredFields(); 
      //We iterate the fields to copy them. You might want to close these too, but for the sake of simplicity I did not tackle with this issue 
      for (int fieldIndex = 0; fieldIndex < fields.length; fieldIndex++) { 
       //We copy the field values of this into the clone 
       fields[fieldIndex].set(newClone, fields[fieldIndex].get(this)); 
      } 
      //newClone is ready and kicking 
      return newClone; 
     } 

     //We need this method to be able to reach the clone method publicly 
     public Object runClone() throws CloneNotSupportedException { 
      return this.clone(); 
     } 

    } 

此代碼是未經測試做到這一點,任何觀察歡迎。

您需要使用從MyCloneable繼承的類的對象。

0

沒有通用的方法來克隆Java中的對象。該類型必須在其公共API中提供一種克隆方法(可能稱爲clone()或其他;無關緊要),並且在Java中沒有用於此類類型的公共超類型。

相關問題