Se entiende comúnmente que la Cloneable
interfaz en Java está rota. Hay muchas razones para esto, que no mencionaré; otros ya lo hicieron. También es la posición de los propios arquitectos de Java .
Mi pregunta es por lo tanto: ¿por qué aún no ha quedado en desuso? Si el equipo central de Java ha decidido que está roto, entonces también deben haber considerado la desaprobación. ¿Cuáles son sus razones para no hacerlo (en Java 8 todavía no está en desuso )?
Cloneable
es ampliamente conocida.Respuestas:
Hay un error enviado en 1997 a Java Bug Database sobre agregar un
clone()
métodoCloneable
, por lo que ya no sería inútil. Se cerró con la resolución "no solucionará" y la justificación fue la siguiente:Entonces, aunque esto no se trata directamente de obsoleto , la razón para no hacer que Cloneable sea "obsoleto" es que el Comité de Revisión Técnica decidió que modificar la documentación existente será suficiente para que esta interfaz sea útil. Y así lo hicieron. Hasta Java 1.4,
Cloneable
se documentó de la siguiente manera:Desde Java 1.4 (que se lanzó en febrero de 2002) hasta la edición actual (Java 8) se ve así:
fuente
clone
método estaba enObject
primer lugar?Object#clone()
produce una instancia de la misma clase que la original sin que esa clase se conozca en tiempo de compilación.La respuesta corta a "¿por qué no está en
Cloneable
desuso?" (o de hecho, por qué no está enX
desuso, para cualquierX
) es que no se ha prestado mucha atención a despreciarlos.La mayoría de las cosas que han quedado en desuso recientemente quedaron en desuso porque existe un plan específico para eliminarlas. Por ejemplo, las
addPropertyChangeListener
yremovePropertyChangeListener
los métodos de LogManager estaban en desuso en Java SE 8 con la intención de dejarlas en Java SE 9. (La razón es que innecesariamente complicadas interdependencias de los módulos.) De hecho, estas API ya se han eliminado desde la primera JDK 9 desarrollo Construye. (Tenga en cuenta que también se eliminaron llamadas de escucha de cambio de propiedad similaresPack200
; consulte JDK-8029806 ).No existe un plan similar para
Cloneable
y paraObject.clone()
.Una respuesta más larga implicaría discutir más preguntas, como qué podría esperarse que suceda con estas API, qué costos o beneficios acumularían la plataforma si se desaprobaran, y qué se comunica a los desarrolladores cuando una API se desaprueba. Exploré este tema en mi reciente charla de JavaOne, Deuda y desaprobación . (Diapositivas disponibles en ese enlace; video aquí .) Resulta que el JDK en sí mismo no ha sido muy consistente en su uso de la degradación. Se ha utilizado para significar varias cosas diferentes, que incluyen, por ejemplo,
Esto es peligroso y debe ser consciente de los riesgos de su utilización (ejemplo:
Thread.stop()
,Thread.resume()
, yThread.suspend()
).Esto se eliminará en una versión futura
Esto es obsoleto y es una buena idea que use algo diferente (ejemplo: muchos de los métodos en
java.util.Date
)Todos estos son significados distintos, y diferentes subconjuntos de ellos se aplican a diferentes cosas que están en desuso. Y algunos subconjuntos de ellos se aplican a cosas que no están en desuso (pero que tal vez deberían estar en desuso).
Cloneable
yObject.clone()
están "rotos" en el sentido de que tienen fallas de diseño y son difíciles de usar correctamente. Sin embargo,clone()
sigue siendo la mejor manera de copiar matrices, y la clonación tiene una utilidad limitada para hacer copias de instancias de clases que se implementan cuidadosamente. Eliminar la clonación sería un cambio incompatible que rompería muchas cosas. Una operación de clonación podría implementarse de una manera diferente, pero probablemente sería más lenta queObject.clone()
.Sin embargo, para la mayoría de las cosas, un constructor de copia es preferible a la clonación. Entonces quizás marcando
Cloneable
sea apropiado como "obsoleto" o "reemplazado" o algo similar. Esto les diría a los desarrolladores que probablemente quieran buscar en otro lado, pero no indicaría que el mecanismo de clonación podría eliminarse en una versión futura. Desafortunadamente, no existe tal marcador.Tal como están las cosas, la "desaprobación" parece implicar la eliminación eventual, a pesar del hecho de que una cantidad cada vez menor de características desaprobadas se han eliminado alguna vez, por lo que la desaprobación no parece justificada por el mecanismo de clonación. Quizás en el futuro se pueda aplicar una marca alternativa que dirija a los desarrolladores a utilizar mecanismos alternativos.
ACTUALIZAR
Agregué un historial adicional al informe de error . Frank Yellin, uno de los primeros implementadores de JVM y coautor de la especificación de JVM, hizo algunos comentarios en respuesta al comentario de "perdido en las brumas del tiempo" en la recomendación de TRC citada en la otra respuesta . He citado las porciones relevantes aquí; El mensaje completo está en el informe de error.
fuente
Object.clone()
al fuego solo porque todos los demás lo deseen, sino que estás dispuesto a razonar y sacar a relucir las cosas buenas.array.clone()
sea necesariamente más rápido que cualquier otra alternativa. Desde la perspectiva API, es la forma más concisa de duplicar una matriz.Arrays.copyOf(array, newlen)
se acerca, pero requiere un parámetro de longitud, que es redundante si no está cambiando la longitud.Thread.suspend()
yThread.stop()
(sin argumentos) son peligrosos, probablemente no se eliminarán, ni se cambiarán para lanzar una excepción incondicional, ¡porque la gente realmente los usa! Presumiblemente están dispuestos a asumir el riesgo. Uno de los factores atenuantes con los oyentes de cambio de propiedad es que se usaron muy raramente, por lo que el impacto de eliminarlos es pequeño.java.beans
podría hacerse independientejava.desktop
ya que los beans son solo una API de biblioteca para propiedades. Desafortunadamente, si profundiza en la API de beans, hay muchas dependencias en AWT. La implementación tiene aún más. Ciertamente, podría ser posible extraerlos, pero hacer eso parece mucho más trabajo que, por ejemplo, desenredar la tala de los frijoles. Todo el esfuerzo de modularización se trata de hacer este desenredado; indudablemente se podría hacer más, pero luego Jigsaw tomaría aún más tiempo.Porque el PCJ no ha creído conveniente hacerlo, y puede que nunca lo haga. Pregúntales. Estás preguntando en el lugar equivocado.
Nadie eliminará nada de la API de Java, debido al requisito de compatibilidad con versiones anteriores. La última vez que sucedió fue el cambio en el modelo de evento AWT entre 1.0 y 1.1 en 1996/7.
fuente
Thread.stop(Throwable)
cambiando su contrato para lanzar siempreUnsupportedOperationException
a la persona que llama (¡no al hilo objetivo!).Thread.stop(Throwable)
la funcionalidad de '' ocurrió en Java 8. De todos modos, el consejo no calificado de "preguntarles" está mal porque hoy el arquitecto jefe de Java es un miembro activo en Stack Overflow. Simplemente no se molesta en responder nada más que preguntas relacionadas con Streams.Cloneable
será eliminado de la API de Java. Estoy preguntando por qué no va a ser depravado. Y creo que este es un lugar perfecto para preguntar.