2009-07-01 26 views
15

Se ho:Confusione circa interfaccia clonabile e Object.clone() in java

class foo implements Cloneable 

e poi fare:

bar = new foo(); 
bar.clone(); 

ottengo una copia senza bisogno di scrivere codice bar.clone() come Normalmente dovrei fare quando implemento un'interfaccia.

La mia comprensione è che le funzioni di un'interfaccia devono essere compilati dalla classe che implementa, e Object.clone() non ha alcuna implementazione (come per la documentazione, "L'oggetto classe non si implementa l'interfaccia Cloneable")

Così da dove viene il mio clone superficiale? Dov'è il codice che implementa bar.clone() se Object.clone() non ha implementazione? Non ho capito bene.

+0

Ti incoraggio ad accettare una risposta o chiedere ulteriori chiarimenti in modo da poter ottenere la risposta giusta :-). – Tom

+0

@Tom sure thing :) – ambertch

risposta

27

Be fare attenzione con il clone. Anzi, lo eviterei completamente. Ho bisogno di mai. MA ... detto questo, la migliore discussione sull'argomento che abbia mai letto è di Joshua Bloch, in Effective Java. Leggi l'articolo 11: "Sostituisci giudiziosamente il clone".

PER FAVORE, fatevi un favore e leggete quell'articolo. In realtà raccomando di leggere l'intero capitolo (e il resto del libro). Tutto quello che devi sapere sul clone e sul perché ti avverto è lì.

Spero che questo aiuti.

+3

+1 per Java efficace. La discussione sulla clonazione è ottima, così come l'intero libro. –

+0

Questa dovrebbe essere l'unica risposta. Data l'eccellente discussione di Joshua Bloch sui difetti di progettazione insiti in Cloneable, si potrebbe quasi dire che è solo un errore di progettazione in Java per cominciare. Stai quasi sempre meglio usando un costruttore di copia/fabbrica statica. –

+2

Il link è "interrotto" :( –

6

Object.clone() ha un'implementazione:

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#clone()

Questo legame spiega l'interfaccia Cloneable: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Cloneable.html

un oggetto deve implementare l'interfaccia Cloneable al fine di chiamare il clone() metodo, altrimenti lancia una CloneNotSupportedException.

Per definizione, tutte le classi in Java estendono la classe Object di base e la classe Object ha un metodo clone() predefinito, anche se Object non implementa Cloneable. Il metodo clone() della classe Object verrà chiamato se non lo si sovrascrive autonomamente.

+0

ah capisco. Ho erroneamente letto i documenti - l'oggetto ha il codice per clone(), non implementa semplicemente il cloneable Quindi qual è il meccanismo per far rispettare l'implementazione clonabile per chiamare class.clone()? Questo è solo qualcosa a cui JRE è consapevole di controllare deliberatamente? – ambertch

+0

La risposta rapida - niente. L'interfaccia definisce il comportamento dell'implementazione di clone() di Object. Se una classe è Cloneable, Object.clone() restituisce una copia, altrimenti genera CloneNotSupportedException. L'interfaccia Cloneable modifica sostanzialmente il comportamento dell'implementazione della sua superclasse di clone(). – Cambium

1

Se ho: "class foo implementa clonabile"

e poi fare: bar = new foo(); bar.clone();

ottengo una copia senza bisogno di scrivere alcun codice bar.clone() come ho normalmente avrebbe bisogno di fare quando ho implementare un'interfaccia.

Ciò funzionerebbe solo se lo si chiama all'interno della classe "pippo", poiché il metodo .clone() ereditato da Object è protetto.

La mia comprensione è che le funzioni di un'interfaccia deve essere riempito nel dalla classe che implementa, e Object.clone() non ha alcuna implementazione (come per la documentazione, "La classe Object non lo fa per sé implementare l'interfaccia Cloneable ")

(1) Object.clone() ha un'implementazione. Effettua una copia superficiale dell'oggetto se l'oggetto implementa Cloneable. (2) Il metodo .clone() non fa parte di alcuna interfaccia. (3) Avere un metodo .clone() e implementare l'interfaccia Cloneable sono cose completamente separate. È necessario implementare l'interfaccia Cloneable solo se si intende utilizzare il metodo clone di Object; tuttavia, questo è il metodo consigliato per scrivere un metodo clone per la classe - per ottenere la sua copia dal metodo della superclasse, che alla fine sale al metodo .

+0

Grazie, sì, sei iscritto - il mio male come ho letto male la frase e confuso "implements coneable" con "avere un'implementazione" – ambertch