É comumente entendido que a Cloneable
interface em Java está quebrada. Há muitas razões para isso, que não mencionarei; outros já fizeram isso. É também a posição dos próprios arquitetos Java .
Minha pergunta é, portanto: por que ainda não foi preterido? Se a equipe principal do Java decidiu que está quebrada, também deve ter considerado a descontinuação. Quais são os motivos deles para fazê-lo (no Java 8 ainda não foi preterido )?
Cloneable
são amplamente conhecidas.Respostas:
Há um bug enviado em 1997 ao Java Bug Database sobre a adição de
clone()
métodoCloneable
, portanto ele não seria mais inútil. Foi fechado com a resolução "não corrigido" e a justificativa é a seguinte:Portanto, embora isso não seja diretamente preterido , o motivo para não tornar o Cloneable "preterido" é que o Comitê de Revisão Técnica decidiu que modificar a documentação existente será suficiente para tornar essa interface útil. E assim eles fizeram. Até o Java 1.4,
Cloneable
foi documentado da seguinte maneira:Desde o Java 1.4 (lançado em fevereiro de 2002) até a edição atual (Java 8), fica assim:
fonte
clone
método estava emObject
primeiro lugar?Object#clone()
produz uma instância da mesma classe que a original, sem que essa classe seja conhecida no momento da compilação.A resposta curta para "por que não está
Cloneable
obsoleta?" (ou, de fato, por que não éX
preterido, para qualquer umX
) é 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
eremovePropertyChangeListener
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 removidasPack200
; consulte JDK-8029806 .)Não existe um plano semelhante para
Cloneable
e paraObject.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()
, eThread.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
eObject.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 queObject.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.
fonte
Object.clone()
no fogo só porque todo mundo quer, mas você está disposto a raciocinar e trazer à tona as coisas boas dele.array.clone()
é necessariamente mais rápido do que quaisquer alternativas. Da perspectiva da API, é a maneira mais concisa de duplicar uma matriz.Arrays.copyOf(array, newlen)
chega perto, mas requer um parâmetro de comprimento, que é redundante se você não estiver alterando o comprimento.Thread.suspend()
eThread.stop()
(no-arg) sejam perigosos, eles provavelmente não serão removidos - ou alterados para gerar uma exceção incondicionalmente - porque as pessoas realmente os usam! Presumivelmente, eles estão dispostos a assumir o risco. Um dos fatores atenuantes dos ouvintes de mudança de propriedade é que eles foram usados muito raramente, portanto o impacto de removê-los é pequeno.java.beans
pode ser feito independente,java.desktop
pois os beans são apenas uma API de biblioteca para propriedades. Infelizmente, se você pesquisar na API de beans, há muitas dependências no AWT. A implementação tem ainda mais. Certamente, pode ser possível extraí-los, mas fazer isso parece muito mais trabalhoso do que, digamos, desagrupar o registro de grãos. Todo o esforço de modularização é sobre fazer esse desembaraço; sem dúvida, mais poderia ser feito, mas o Jigsaw levaria ainda mais tempo.Porque o JCP não achou oportuno fazê-lo, e talvez nunca o faça. Pergunte a eles. Você está perguntando no lugar errado.
Ninguém jamais removerá nada da API Java, devido ao requisito de compatibilidade com versões anteriores. A última vez que aconteceu foi a alteração no modelo de evento AWT entre 1,0 e 1,1 em 1996/7.
fonte
Thread.stop(Throwable)
alterando seu contrato para sempre serem lançadosUnsupportedOperationException
no chamador (não no segmento de destino!).Thread.stop(Throwable)
funcionalidade do aconteceu em Java 8. De qualquer forma, o conselho não qualificado de "pedir a eles" está errado, porque hoje o próprio arquiteto-chefe Java é um membro ativo do Stack Overflow. Ele simplesmente não se incomoda em responder nada além de perguntas relacionadas ao Streams.Cloneable
será removido da API Java. Estou perguntando por que não será depreciado. E acho que este é o lugar perfeito para perguntar.