La risposta breve a "perché non è Cloneable
deprecato?" (o, in effetti, perché non è X
deprecato, per nessuno X
) è che non è stata prestata molta attenzione a deprecarli.
La maggior parte delle cose che sono state deprecate di recente sono state deprecate perché esiste un piano specifico per rimuoverle. Ad esempio, i metodi addPropertyChangeListener
e removePropertyChangeListener
di LogManager sono stati deprecati in Java SE 8 con l'intenzione di rimuoverli in Java SE 9. (Il motivo è che hanno inutilmente complicate interdipendenze tra i moduli.) In effetti, queste API sono già state rimosse dallo sviluppo iniziale di JDK 9 costruisce. (Notare che sono state rimosse anche chiamate di listener di modifica proprietà simili Pack200
; vedere JDK-8029806 .)
Nessun piano simile esiste per Cloneable
e Object.clone()
.
Una risposta più lunga implicherebbe la discussione di ulteriori domande, come ad esempio cosa ci si potrebbe aspettare da queste API, quali costi o benefici maturerebbero sulla piattaforma se fossero deprecati e cosa viene comunicato agli sviluppatori quando un'API è deprecata. Ho esplorato questo argomento nel mio recente discorso su JavaOne, Debito e deprecazione . (Diapositive disponibili su quel link; video qui .) Si scopre che il JDK stesso non è stato molto coerente nel suo uso della deprecazione. È stato usato per significare diverse cose, tra cui ad esempio
Questo è pericoloso e si dovrebbe essere consapevoli dei rischi di utilizzo (ad esempio: Thread.stop()
, Thread.resume()
, e Thread.suspend()
).
Questo verrà rimosso in una versione futura
Questo è obsoleto ed è una buona idea usare qualcosa di diverso (esempio: molti dei metodi in java.util.Date
)
Tutti questi sono significati distinti e diversi sottoinsiemi si applicano a cose diverse che sono deprecate. E alcuni sottoinsiemi si applicano a cose che non sono deprecate (ma che forse dovrebbero essere deprecate).
Cloneable
e Object.clone()
sono "rotti" nel senso che hanno difetti di progettazione e sono difficili da usare correttamente. Tuttavia, clone()
è ancora il modo migliore per copiare le matrici e la clonazione ha un'utilità limitata per creare copie di istanze di classi che vengono implementate con cura. Rimuovere la clonazione sarebbe un cambiamento incompatibile che spezzerebbe molte cose. Un'operazione di clonazione potrebbe essere reimplementata in un modo diverso, ma probabilmente sarebbe più lenta di Object.clone()
.
Tuttavia, per la maggior parte delle cose un costruttore di copie è preferibile alla clonazione. Quindi, forse contrassegnare Cloneable
come "obsoleto" o "sostituito" o qualcosa di simile sarebbe appropriato. Questo direbbe agli sviluppatori che probabilmente vogliono cercare altrove, ma non segnalerebbe che il meccanismo di clonazione potrebbe essere rimosso in una versione futura. Sfortunatamente, non esiste un marcatore simile.
Allo stato attuale, la "deprecazione" sembra implicare un'eventuale rimozione - nonostante il fatto che un numero incredibilmente piccolo di funzioni deprecate sia mai stato rimosso - e quindi la deprecazione non sembra giustificata per il meccanismo di clonazione. Forse in futuro può essere applicato un marchio alternativo che indichi agli sviluppatori di utilizzare invece meccanismi alternativi.
AGGIORNARE
Ho aggiunto un po 'di cronologia aggiuntiva alla segnalazione di bug . Frank Yellin, uno dei primi implementatori di JVM e coautore della specifica JVM, ha fatto alcuni commenti in risposta al commento "perso nella notte dei tempi" nella raccomandazione TRC citata nell'altra risposta . Ho citato le parti pertinenti qui; il messaggio completo è nella segnalazione di bug.
Cloneable non ha metodi per lo stesso motivo di Serializable. Clonabile indica una proprietà della classe, piuttosto che dire specificamente qualcosa sui metodi supportati dalla classe.
Prima della riflessione, avevamo bisogno di un metodo nativo per creare una copia superficiale di un oggetto. Quindi è nato Object.clone (). Era anche chiaro che molte classi avrebbero voluto sovrascrivere questo metodo e che non tutte le classi avrebbero voluto essere clonate. Quindi Cloneable è nato per indicare l'intenzione del programmatore.
Quindi, in breve. Lo scopo di Cloneable non era quello di indicare che avevi un metodo clone () pubblico. Indicava che eri disposto a essere clonato usando Object.clone () e dipendeva dall'implementazione decidere se rendere pubblico clone ().