2015-06-21 12 views
5

Voglio clonare un dato oggetto.Come convince il compilatore un oggetto è clonabile (java)?

se faccio questo

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; 
    } 
} 

questo non funzionerà becuase o.clone() è protetto.

se faccio questo invece

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

non funzionerà o perché Cloneable è un'interfaccia vuoto.

quindi come faccio a convincere il compilatore che è possibile clonare o?

+0

@immibis, non credo che il tuo commento aggiunga molto valore all'essere onesti. – aioobe

+2

È necessario rendere la classe implementare 'Cloneable' e implementare il metodo' clone'. – Rishav

+1

Da doc: "Una classe implementa l'interfaccia Cloneable per indicare al metodo Object.clone() che è legale per quel metodo eseguire una copia field-for-field delle istanze di quella classe." – Rishav

risposta

2

Non è possibile, quando si implementa clone() è necessario conoscere la clonazione, è necessario conoscere la classe di implementazione.

Un'alternativa alla clonazione consiste nell'utilizzare il costruttore di copie, che ha lo stesso problema, è necessario conoscere la classe.

Alcuni dicono di non utilizzare clone, altri dicono definire la propria interfaccia, ad es: Copyablehttp://c2.com/cgi/wiki?CloneableDoesNotImplementClone

-1

L'interfaccia java.lang.Cloneable deve essere implementata dalla classe il cui oggetto clone vogliamo creare. Se non implementiamo l'interfaccia Cloneable, il metodo clone() genera CloneNotSupportedException.

Il metodo clone() è definito nella classe Object. Sintassi del metodo clone() è la seguente:

protected Object clone() throws CloneNotSupportedException 

Quindi la classe dovrebbe essere come

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

La domanda era come clonare 'o'. – immibis

1

si può fare con la riflessione

//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(); 
     } 

    } 

Questo codice è testato, nessuna osservazione è benvenuto.

È necessario utilizzare oggetti di classi ereditate da MyCloneable.

0

Non esiste un modo generale per clonare un oggetto in Java. Il tipo deve fornire un metodo per clonare (che può essere chiamato clone() o qualcos'altro, non ha importanza) nella sua API pubblica e non esiste un supertipo comune per tali tipi in Java.