2011-11-19 17 views
11

per clonare l'oggetto è necessario implementare l'interfaccia 'clonabile'. perché qui la mia classe è un file jar (intendo API). quindi non posso modificare la classe. Ho sentito che tutte le classi estendono la classe dell'oggetto base e questa classe oggetto implementa l'interfaccia clonabile. questo significa che possiamo clonare direttamente l'oggetto senza implementare l'interfaccia. se è così nella mia eclissi non ho alcuna possibilità di clonare l'oggetto. c'è un altro modo per clonare l'oggetto senza implementare l'interfaccia clonabile. Spiega per favore.clonazione di oggetti con l'implementazione dell'interfaccia clonabile

+1

Perché pensi di doverlo fare? Forse starai meglio a dirci il problema generale che stai cercando di risolvere piuttosto che i passi di programmazione che ritieni siano necessari per risolvere questo problema. In altre parole, potresti avere delle cose sbagliate. –

+0

Per i commenti nelle risposte, penso che l'OP voglia un costruttore di copie. – msandiford

+0

hi hovercraft. qui sto spiegando chiaramente il mio problema. Ho una classe chiamata XYZ e ho un metodo che restituisce un oggetto di questa classe XYZ. private XYZ getObject() {return obj; } e ho creato un oggetto chiamando questo metodo. XYZ obj1 = getObject(); ecco il problema in realtà voglio creare un altro oggetto senza chiamare di nuovo il metodo. e non posso modificare la classe XYZ qui. volevo fare XYZ obj2 = (XYZ) obj1.clone(); ma non posso implementare l'interfaccia 'clonabile' sulla mia classe XYZ. quindi c'è un altro modo per creare un altro oggetto per questa classe. – ran

risposta

5

la classe Java Object non implementa l'interfaccia Cloneable. Ha tuttavia il metodo clone(). Ma questo metodo è protected e getterà CloneNotSupportedException se chiamato su un oggetto che non implementa l'interfaccia Cloneable. Quindi se non riesci a modificare la classe che vuoi clonare sei sfortunato e dovrai trovare un altro modo per copiare l'istanza.

Va notato tuttavia che il sistema clone in Java è pieno di buchi e generalmente non più utilizzato. Dai un'occhiata a questo interview con Josh Bloch del 2002 che spiega alcuni dei problemi.

+0

c'è un altro modo per clonare l'oggetto senza implementare l'interfaccia clonabile ... grazie per la tua risposta – ran

+0

"Va notato tuttavia che il sistema clone di Java è pieno di buchi e generalmente non è più utilizzato." - Puoi aggiungere un riferimento per la dichiarazione? –

+0

È possibile creare una nuova istanza utilizzando un costruttore e copiare lo stato richiesto attraverso. La fattibilità di ciò dipende in realtà dalla classe dell'oggetto che si desidera copiare. – orien

0

Tentativo di richiamare il metodo clone su una classe che non implementa Cloneable genera Eccezione CloneNotSupported e nessuna classe Object non implementa Cloneable.

Ecco l'javadoc dal metodo clone di classe Object

CloneNotSupportedException if the object's class does not 
*    support the <code>Cloneable</code> interface. Subclasses 
*    that override the <code>clone</code> method can also 
*    throw this exception to indicate that an instance cannot 
*    be cloned. 

anche oggetto metodo # clone è protetto quindi è necessario implementare il metodo clone nella classe e renderlo pubblico in modo che possa essere accessibile a classi che creano oggetti della tua classe che possono quindi richiamare il clone. Un buon esempio è il modo in cui è clone di implementare in ArrayList

ArrayList implementa clonabile come qui di seguito public class ArrayList estende AbstractList implementa List, RandomAccess, Cloneable, java.io.Serializable

e poi implementa il metodo clone:

/** 
* Returns a shallow copy of this <tt>ArrayList</tt> instance. (The 
* elements themselves are not copied.) 
* 
* @return a clone of this <tt>ArrayList</tt> instance 
*/ 
public Object clone() { 
try { 
    ArrayList<E> v = (ArrayList<E>) super.clone(); 
    v.elementData = Arrays.copyOf(elementData, size); 
    v.modCount = 0; 
    return v; 
} catch (CloneNotSupportedException e) { 
    // this shouldn't happen, since we are Cloneable 
    throw new InternalError(); 
} 
} 
+0

ciao gaurav, come ho già detto non posso implementare l'interfaccia clonabile sulla mia classe. ma voglio creare l'oggetto duplicato con un nome diverso dell'oggetto esistente. C'è un altro modo di fare questo. – ran

+0

Se si sta chiedendo se è possibile clonare un oggetto di una classe che non è possibile modificare. La risposta è no. In teoria, è possibile utilizzare la reflection per accedere alle variabili della classe e quindi essere in grado di ottenere e replicare il suo stato, ma dipende dal Security manager se si è autorizzati ad accedere ai membri privati ​​della classe. Anche in questo caso, anche in questo caso, la copia profonda potrebbe non essere possibile. –

+0

Probabilmente dovresti usare un costruttore di copia in questo caso piuttosto che "clone()". Il primo link in google è questo: http://www.javapractices.com/topic/TopicAction.do?Id=12 – msandiford

0

Il metodo clone() nella classe Object è protetto, il che significa che tutte le classi lo erediteranno con il modificatore di accesso protetto, quindi se provate ad accedervi al di fuori di quella classe senza clonarlo non lo vedrete, inoltre vi verrà lanciato CloneNotSupportedException se si tenta di richiamarlo senza implementare l'interfaccia Cloneable.

Nel caso in cui si stia cercando di creare un comportamento di clonazione, è necessario scrivere un nuovo metodo nella classe e quindi creare una copia di tutti i campi in esso, è fondamentalmente come creare una nuova copia di un stato esistente di un oggetto.

public class TestCloneable { 
private String name = null; 

/** 
* @param name the name to set 
*/ 
public void setName(String name) { 
    this.name = name; 
} 

/** 
* @return the name 
*/ 
public String getName() { 
    return name; 
} 


public TestCloneable createCopy(){ 
    TestCloneable testCloneable = new TestCloneable(); 
    testCloneable.setName(this.getName()); 
    return testCloneable; 
} 

}

5

di solito le migliori pratiche per evitare clone() in ogni caso, perché è difficile da fare correttamente (http://www.javapractices.com/topic/TopicAction.do?Id=71). Forse la classe in questione ha un costruttore di copie?

In alternativa, se si implementa Serializable o Externalizable, è possibile copiarlo profonda scrivendo ad un flusso di byte e la lettura di nuovo nel

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
ObjectOutputStream oos = new ObjectOutputStream(baos); 
oos.writeObject(this); 
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
ObjectInputStream ois = new ObjectInputStream(bais); 
Object deepCopy = ois.readObject(); 

(da http://www.jguru.com/faq/view.jsp?EID=20435).Questo è semplice e veloce, ma non bello ... In genere lo considererei l'ultima risorsa.

+0

hi kyle. grazie per la tua risposta. ma non ho capito esattamente di questo. puoi per favore dirmi nel mio caso come posso farlo? – ran

+0

Un costruttore di copia sarà simile a: pubblico XYZ (XYZ toCopy). Invece di chiamare o.clone(), chiameresti nuovo XYZ (o). La parte serializzabile significa che se XYZ può essere scritto su uno stream, allora puoi scriverlo su uno stream (in realtà solo una serie di byte in memoria) e poi leggerlo da quel flusso, creando effettivamente una copia. – kylewm

+0

La limitazione di un costruttore di copie è che è necessario conoscere il tipo di classe al momento della creazione del codice. 'public XYZ (toCopy)' non funzionerà se passo in una sottoclasse di 'XYZ'. –

0

Non è obbligatorio per implementare l'interfaccia clonabile di fare un clone di un oggetto. È possibile scrivere il proprio metodo di clonazione nella classe di cui si desidera clonare l'oggetto.

+1

Questo non fornisce una risposta alla domanda. Una volta che hai [reputazione] sufficiente (https://stackoverflow.com/help/whats-reputation) sarai in grado di [commentare qualsiasi post] (https://stackoverflow.com/help/privileges/comment); invece [fornisci risposte che non richiedono chiarimenti da parte del richiedente] (https: //meta.stackexchange.com/domande/214173/why-do-i-need-50-reputazione-to-commento-what-can-i-do-, invece). - [Dalla recensione] (/ recensione/post di bassa qualità/18867158) –