Pregunta ¿Diferencia entre una API obsoleta y una heredada?


Estaba estudiando las API heredadas en Java's Collection Framework y aprendí que clases como Vector y HashTable han sido reemplazados por ArrayList y HashMap.

Sin embargo, aún NO están en desuso, y se consideran heredados cuando, en esencia, la depreciación se aplica a las funciones del software que se reemplazan y deben evitarse, por lo tanto, no estoy seguro de cuándo se considera que una API es heredada y cuándo está obsoleta.


32
2018-05-20 11:36


origen


Respuestas:


Del glosario oficial de Sun:

deprecación: Se refiere a una clase, interfaz, constructor, método o campo que ya no se recomienda, y puede dejar de existir en una versión futura.

De la guía de cómo y cuándo desaprobar:

Es posible que haya escuchado el término "humor que se autodesprecia" o humor que minimiza la importancia del orador. Una clase o método obsoleto es así. Ya no es importante. De hecho, es tan importante que ya no deberías usarlo, ya que ha sido reemplazado y puede dejar de existir en el futuro.

los @Deprecated la anotación fue un paso más allá y advierte del peligro:

Un elemento de programa anotado @Deprecated es uno que se desaconseja a los programadores, por lo general porque es peligrosoo porque existe una mejor alternativa

Referencias


Tenga en cuenta que el glosario oficial no define qué significa "legado". Con toda probabilidad, puede ser un término que Josh Bloch usó sin una definición exacta. La implicación, sin embargo, es siempre que una clase heredada nunca debe ser utilizada en un código nuevo, y existe un mejor reemplazo.

Tal vez un código anterior que utiliza una clase heredada pero no desaprobada no requiere ninguna acción, ya que, al menos por el momento, no están en peligro de dejar de existir en la versión futura.

Por el contrario, la obsolescencia advierte explícitamente que pueden dejar de existir, por lo que se deben tomar medidas para migrar al reemplazo.


Citas de Effective Java 2nd Edition

Para comparar cómo se usan estos términos en contexto, estas son citas del libro donde la palabra "obsoleto" aparece:

Punto 7: evitar finalizadores: Los únicos métodos que afirman garantizar la finalización son System.runFinalizersOnExit y su gemelo malvado Runtime.runFinalizersOnExit. Estos métodos son fatalmente defectuosos y han sido desaprobados.

Elemento 66: sincroniza el acceso a datos mutables compartidos: Las bibliotecas proporcionan el Thread.stop método, pero este método fue desaprobado hace mucho tiempo porque es intrínsecamente inseguro - su uso puede provocar daños en los datos.

Elemento 70: Seguridad de hilo de documento: Los System.runFinalizersOnExit método es thread-hostile y ha quedado obsoleto.

Ítem ​​73: evitar grupos de hilos: Te permiten aplicar ciertos Thread primitivos a un grupo de hilos a la vez. Varias de estas primitivas han quedado obsoletas, y el resto se usan con poca frecuencia. [...] los grupos de hilos están obsoletos.

Por el contrario, estas son las citas donde la palabra "legado" aparece:

Ítem ​​23: No use tipos crudos en el nuevo código: Se proporcionan para compatibilidad e interoperabilidad con código heredado que es anterior a la introducción de genéricos.

Ítem ​​25: Prefiere listas a arreglos: Erasure es lo que permite que los tipos genéricos interactúen libremente con el código heredado que no usa genéricos.

Ítem ​​29: Considere contenedores heterogéneos tipo seguro: Estos contenedores son útiles para buscar quién agrega un elemento incorrectamente tipado a una colección en una aplicación que mezcla código genérico y heredado.

Ítem ​​54: Usar métodos nativos juiciosamente: Proporcionan acceso a las bibliotecas de código heredado, que a su vez podría proporcionar acceso a datos heredados. [...] También es legítimo usar métodos nativos para acceder al código heredado. [...] Si debe usar métodos nativos para acceder a recursos de bajo nivel o bibliotecas heredadas, use el menor código nativo posible y pruébelo a fondo.

Ítem ​​69: Prefiere las utilidades de concurrencia para esperar y notificar: Si bien siempre debe usar las utilidades de simultaneidad con preferencia a wait y notify, es posible que tengas que mantener el código heredado que usa wait y notify.

Estas citas no fueron cuidadosamente seleccionadas: son TODAS las instancias donde la palabra "obsoleto" y "legado" aparecer en el libro. El mensaje de Bloch es claro aquí:

  • Métodos obsoletos, p. Thread.stop, son peligrosos y deberían Nunca ser utilizado en absoluto.
  • Por otro lado, p. wait/notify puede permanecer en el código heredado, pero no debe usarse en un código nuevo.

Mi propia opinión subjetiva

Mi interpretación es que desaprobar algo es admitir que es un error, y nunca fue bueno para empezar. Por otro lado, clasificar que algo es un legado es admitir que fue lo suficientemente bueno en el pasado, pero ha cumplido su propósito y ya no es lo suficientemente bueno para el presente y el futuro.


25
2018-05-20 11:49



Una interpretación común es que Deprecated significa que se eliminará en el futuro cercano, y Legacy significa que seguirá siendo compatible con versiones anteriores u otras razones.

Ambos significan que no deben ser utilizados por un nuevo código.

En el caso del JDK, incluso el código obsoleto se mantendrá, ya que la compatibilidad con versiones anteriores es muy importante para Java JDK.


13
2018-05-20 11:38



La depreciación a menudo denota que hay una intención de eliminar la funcionalidad en algún momento en el futuro, mientras que el legado simplemente implica que no debe usarse en un código nuevo si es posible (aunque puede ser necesario por razones de interoperabilidad).


0
2018-05-20 11:39



los Obsoleto la anotación proporciona una definición formal de una API obsoleta. No creo que exista una definición formal para las clases heredadas. En realidad, ambos significan que la clase no debe usarse en un código nuevo.


0
2018-05-20 11:46



Tengo una sugerencia: el legado se refiere al código que se escribió en el pasado, obsoleto se refiere al consejo de no usarlo más. Aún puede usar la API en desuso, pero no puede escribir el código heredado, porque lo está escribiendo en este momento. Sólo en mi humilde opinión


0
2018-05-20 11:46



La depreciación significa que es malo y no debe usarse, File.toURL() es un buen ejemplo, ya que no crea URL correctas a partir de archivos con espacios en la ruta. Simplemente no está haciendo lo que debería, pero dado que el código existente podría estar utilizando soluciones que se romperían si el error se soluciona

El legado solo significa que es viejo y que hay formas de hacer algo que generalmente, pero no necesariamente, son mejores. Vector es un buen ejemplo, es un List implementación, pero todavía tiene algunas fea basura de los días anteriores a la API de Colecciones (es decir, List) fue diseñado. También está sincronizado, lo que significa que tiene que pagar la tarifa de sincronización incluso cuando la usa en un escenario de subproceso único (excepto en algunas situaciones donde la VM es inteligente). ArrayList es mejor si desea una implementación de lista con respaldo de matriz ya que no está sincronizada, y Collections.synchronizedList es más flexible cuando se quiere una lista sincronizada, ya que es un contenedor que se puede usar con todas las implementaciones de listas (listas enlazadas, listas de Arrays.asList(T...), etc.) Sin embargo, si hacer sucede que quiere una implementación de lista sincronizada y respaldada por arreglos, luego Vector está bien.


0
2018-05-20 12:36



Mi interpretación es que el código heredado simplemente tiene contrapartes más nuevas que hacen el trabajo mejor. Sin embargo, continuará recibiendo correcciones de errores y otro soporte. El código obsoleto, por otro lado, no es compatible y no recibirá correcciones de errores dedicadas.


0
2018-05-20 14:30