2015-06-21 10 views
5

Chcę sklonować dany obiekt.Jak przekonać kompilator obiekt jest klonowalne (java)?

jeśli mogę to zrobić

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

to nie zadziała, ponieważ posiadał o.clone() jest chronione.

jeśli mogę to zrobić zamiast

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

nie będzie działać albo dlatego Cloneable jest pusty interfejs.

więc w jaki sposób mogę przekonać kompilator, że można klonować?

+0

@immibis, nie sądzę, że twój komentarz dodaje wiele wartości, szczerze mówiąc. – aioobe

+2

Musisz sprawić, by twoja klasa implementowała 'Cloneable' i implementowała metodę' clone'. – Rishav

+1

Z dokumentu: "Klasa implementuje interfejs Klonowalny, aby wskazać metodzie Object.clone(), że legalna dla tej metody jest utworzenie kopii instancji tej klasy w polu." – Rishav

Odpowiedz

2

Nie możesz, podczas implementacji clone(), trzeba wiedzieć, co się klonuje, musisz znać klasę implementacji.

Alternatywą dla klonowania jest użycie konstruktora kopii, który ma ten sam problem, musisz znać klasę.

Niektórzy mówią, że nie wolno używać klon, inni mówią zdefiniować własny interfejs, np: Copyablehttp://c2.com/cgi/wiki?CloneableDoesNotImplementClone

-1

musi zostać zaimplementowany przez klasę, której klon obiektu chcemy utworzyć. Jeśli nie implementujemy interfejsu Cloneable, metoda clone() generuje CloneNotSupportedException.

Metoda clone() jest zdefiniowana w klasie Object. Składnia metody clone() jest następujący:

protected Object clone() throws CloneNotSupportedException 

Więc twoja klasa powinna być jak

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

Pytanie brzmiało, jak sklonować 'o'. – immibis

1

Można zrobić to z refleksji

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

    } 

Ten kod jest niesprawdzone, każda obserwacja jest Witamy.

Musisz używać obiektów klas odziedziczonych po MyCloneable.

0

Nie ma ogólnego sposobu klonowania obiektu w Javie. Typ musi zapewniać metodę klonowania (która może być nazywana clone() lub coś innego, nie ma znaczenia) w jej publicznym interfejsie API i nie ma typowego nadtypu dla takich typów w Javie.

Powiązane problemy