A resposta curta para "por que não está Cloneable
obsoleta?" (ou, de fato, por que não é X
preterido, para qualquer um X
) é que não houve muita atenção para preteri-los.
A maioria das coisas que foram descontinuadas recentemente foram descontinuadas porque existe um plano específico para removê-las. Por exemplo, os métodos addPropertyChangeListener
e removePropertyChangeListener
do LogManager foram descontinuados no Java SE 8 com a intenção de removê-los no Java SE 9. (O motivo é que eles complicam desnecessariamente as interdependências de módulos.) De fato, essas APIs já foram removidas do desenvolvimento inicial do JDK 9 constrói. (Observe que chamadas de ouvinte de alteração de propriedade semelhantes também foram removidas Pack200
; consulte JDK-8029806 .)
Não existe um plano semelhante para Cloneable
e para Object.clone()
.
Uma resposta mais longa envolveria a discussão de perguntas adicionais, como o que se poderia esperar dessas APIs, quais custos ou benefícios acumulariam a plataforma se fossem preteridos e o que está sendo comunicado aos desenvolvedores quando uma API é preterida. Eu explorei esse tópico em minha recente palestra sobre JavaOne, Dívida e Deprecação . (Slides disponíveis nesse link; vídeo aqui .) Acontece que o JDK em si não tem sido muito consistente em seu uso de depreciação. Tem sido usado para significar várias coisas diferentes, incluindo, por exemplo,
Isso é perigoso e você deve estar ciente dos riscos de usá-lo (exemplo: Thread.stop()
, Thread.resume()
, e Thread.suspend()
).
Isso será removido em uma versão futura
Isso é obsoleto e é uma boa ideia usar algo diferente (exemplo: muitos dos métodos em java.util.Date
)
Todos esses são significados distintos, e diferentes subconjuntos deles se aplicam a coisas diferentes que foram preteridas. E alguns subconjuntos aplicam-se a coisas que não são preteridas (mas que talvez devam ser preteridas).
Cloneable
e Object.clone()
estão "quebrados" no sentido de que possuem falhas de design e são difíceis de usar corretamente. No entanto, clone()
ainda é a melhor maneira de copiar matrizes e a clonagem tem alguma utilidade limitada para fazer cópias de instâncias de classes cuidadosamente implementadas. Remover a clonagem seria uma alteração incompatível que quebraria muitas coisas. Uma operação de clonagem poderia ser reimplementada de uma maneira diferente, mas provavelmente seria mais lenta que Object.clone()
.
No entanto, para a maioria das coisas, um construtor de cópias é preferível à clonagem. Então, talvez marcar Cloneable
como "obsoleto" ou "substituído" ou algo semelhante seja apropriado. Isso indicaria aos desenvolvedores que eles provavelmente querem procurar em outro lugar, mas não indicaria que o mecanismo de clonagem possa ser removido em uma versão futura. Infelizmente, esse marcador não existe.
No momento, "depreciação" parece implicar uma remoção eventual - apesar do fato de um número extremamente pequeno de recursos obsoletos ter sido removido - e, portanto, a depreciação não parece justificada para o mecanismo de clonagem. Talvez no futuro possa ser aplicada uma marcação alternativa que instrua os desenvolvedores a usar mecanismos alternativos.
ATUALIZAR
Adicionei um histórico adicional ao relatório de erros . Frank Yellin, um dos primeiros implementadores da JVM e co-autor da especificação da JVM, fez alguns comentários em resposta ao comentário "perdido nas brumas do tempo" na recomendação TRC citada na outra resposta . Eu citei as partes relevantes aqui; a mensagem completa está no relatório de erros.
Cloneable não tem métodos pela mesma razão que Serializable não. Cloneable indica uma propriedade da classe, em vez de dizer especificamente algo sobre os métodos que a classe suportava.
Antes da reflexão, precisávamos de um método nativo para fazer uma cópia superficial de um Objeto. Assim, Object.clone () nasceu. Também ficou claro que muitas classes gostariam de substituir esse método e que nem todas as classes gostariam de ser clonadas. Daí Cloneable nasceu para indicar a intenção do programador.
Então, em suma. O objetivo do Cloneable não era indicar que você tinha um método público clone (). Era para indicar que você estava disposto a ser clonado usando Object.clone (), e cabia à implementação decidir se tornaria público ou não o clone ().