2009-04-02 17 views

risposta

36

In sostanza, si tratta di un'interfaccia rotto. Ken Arnold e Bill Venners ne hanno discusso nel Java Design Issues.

Arnold:

Se dovessi essere Dio, a questo punto, e molte persone sono probabilmente contenta io non sono, direi disapprovare Cloneable e hanno un Copyable, perché Cloneable ha problemi. Oltre al fatto che è errato, lo Cloneable non contiene il metodo clone. Ciò significa che non puoi verificare se qualcosa è un'istanza di Cloneable, trasmetterla a Cloneable e invocare clone. Devi usare di nuovo il riflesso, che è terribile. Questo è solo un problema, ma sicuramente risolverei.

+0

Il design è stupido. Mi chiedo perché Sun non abbia mai risolto questo problema. – tactoth

+0

Perché non è stato corretto in Java 8? Non sono state rimosse/modificate parti inefficaci di Java? –

+3

È "rotto" perché alcuni lo dicono? "Cloneable non contiene il metodo clone" Sì, e la sua documentazione non ha mai detto che sarebbe. "Ciò significa che non puoi testare se qualcosa è un'istanza di Cloneable, lanciarlo su Cloneable e invocare il clone." Di nuovo, questo non è affatto lo scopo di "Cloneable". 'Cloneable' è solo per rendere' Object.clone() 'lanciare un'eccezione o meno. Non è mai stata un'interfaccia per invocare il 'clone'. Forse sarebbe bello se Java avesse una tale interfaccia, ma la mancanza di uno non rende un'altra interfaccia ('Cloneable') interrotta. – newacct

10

Vedere questo bug nel database di bug Java:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4098033

In sostanza, si tratta di un difetto di progettazione nelle versioni precedenti di Java che non hanno intenzione di risolvere nell'interfaccia Cloneable come ciò possa rompere la compatibilità con alcuni codici esistenti.

+0

mi chiedo perché non hanno aggiunto l'interfaccia 'Copyable' a Java 1.2 ed oltre ... – EpicPandaForce

+0

@EpicPandaForce Probabilmente perché non vogliamo imitare C++ in determinate situazioni. La clonazione dovrebbe essere utilizzata con cura, il più delle volte non raggiunge ciò che vuoi ottenere. La cosa mancante in Java è avere i parametri 'const', ma copiare ogni istanza dell'oggetto (mutabile) non è una buona soluzione. E sì, ci sono alcune cose in cui Java fa schifo, e questo è uno di questi.Usa Kotlin/classi di dati. –

1

Poiché il metodo clone è implementato nella classe Object a causa della sua condizione "speciale": la copia di memoria di oggetti di qualsiasi tipo.

6

In Java, c'è questo concetto di interfacce marker. L'interfaccia Cloneable non ha metodi o campi e serve solo a identificare la semantica dell'essere clonabile.

dal sito dev-x:

Spesso ci si imbatte in interfacce in Java che non hanno un comportamento. In altre parole, sono solo definizioni di interfaccia vuote. Questi sono noti come interfacce marcatore. Alcuni esempi di interfacce marcatore nella Java API includono:

+1

Non penso che sia un concetto strano. A volte è utile essere in grado di vedere se qualcosa può agire come un tipo alternativo. Come altri hanno già detto, Cloneable è rotto però. –

+0

Dovrebbero funzionare come mixin. Non è il mio meccanismo preferito in un linguaggio fortemente tipizzato come java ma ha senso per Serializable, sorta. – wds

+5

@Serializable avrebbe avuto più senso. O almeno lo avrebbe fatto se le annotazioni fossero arrivate un decennio prima. –

5

Sul progetto di lavoro su, abbiamo creato un'interfaccia chiamata PublicCloneable, contiene il metodo clone e specifica che è pubblico.

Trovo che questo sia utile: il fatto che esista un metodo di clonazione, ma non è possibile accedervi, non aiuta molto.

public interface PublicCloneable extends Cloneable { 
    public Object clone(); 
} 
+1

Quale sarebbe il modo di utilizzare questa interfaccia (PublicConeable)? – Otto

+0

@Otto: ad esempio, un CloneHelper con un metodo public PublicCloneable copia pubblica (PublicCloneable obj), che verifica null o semplicemente copia (Object obj) e controlla sia null che instanceof PublicCloneable –

+0

Quando si restituisce un oggetto da un locale cache per esempio ... Detto questo, serializzare/deserializzare è probabilmente più sicuro. –