2009-06-07 1918 views
6

Dado que this question ha vuelto a tener cuatro votos para cerrar, trato de volver a hacer una pregunta más limitada que espero que la comunidad vea más favorablemente.¿Qué diseños de Java se hacen explícitamente para respaldar la compatibilidad hacia atrás?

Qué decisiones específicas de diseño en Java se documentan para que no se hagan porque esa fue la decisión de diseño preferida, sino más bien porque era necesario para admitir la compatibilidad con versiones anteriores.

El caso obvio es Generics, donde no se puede detectar el parámetro de tipo en tiempo de ejecución. (Por lo que no puede hacer:

public void addEmptyMember(List<?> someList) { 
     if (someList instanceof List<String>) { 
      ((List<String>) someList).add(""); 
     } 
} 

¿Qué otros ejemplos de este tipo existen en el diseño de lenguajes y API estándar

Respuesta

3

Debido a esta pregunta no tiene una única respuesta correcta, no estoy seguro de si? le irá mejor que su otra pregunta.

Tres características que puedo pensar (además del borrado genérico, que ya ha mencionado) que hicieron compromisos en nombre de la compatibilidad con versiones anteriores fueron la nueva sintaxis de bucle, varargs y autoboxing.

la nueva sintaxis de bucle probablemente debería haber leído for (item in List), pero eso hubiera requerido que in fuera una palabra reservada. Esto causaría numerosos problemas de compatibilidad con versiones anteriores, entre los cuales el hecho de que System.in debería cambiarse de nombre.

varargs y autoboxing agregaron las posibilidades de ambigüedad. Por ejemplo, si pasa una matriz de Objetos a un método que acepta Object... ¿significa eso que la matriz se debe pasar como la matriz vararg o como un elemento de la matriz vararg? Esto se vuelve aún más complicado si hay sobrecargas. Autoboxing tiene problemas de ambigüedad similares con la sobrecarga. La solución a estos dos problemas fue establecer como regla que al resolver llamadas de método, primero se resuelven con las reglas anteriores a la 1.5 (es decir, sin autoboxing, y Object... se trata como Object[]). Solo si la llamada al método no se puede resolver con las reglas anteriores a la 1.5 se consideran las nuevas 1.5 reglas.

+0

¿Es el tercero realmente elegido por compatibilidad con versiones anteriores como la única razón principal? Me parece que tiene sentido incluso sin tener en cuenta la compatibilidad con versiones anteriores. –

+4

En cualquier implementación de varargs que estaba en el lenguaje desde el principio, querría que hubiera una sintaxis separada para "explotar esta matriz y pasar sus elementos como los argumentos en las varillas".(Por ejemplo, la notación de llamada * args en python, o incluso la función apply en lisp). No querían hacer esto en Java, sin embargo, porque querían poder "actualizar" funciones API existentes para usar varargs mientras tener todas las llamadas antiguas (que esperaban una matriz) para que funcionen. –

2

Otra sería todas las clases y métodos que ya están en desuso para las versiones múltiples, pero que simplemente no desaparecerán. Los más notables son los diversos métodos Thread, que están en desuso.

+2

Ciertamente cierto. Recuerdo cuando hicieron que System.getenv() lanzara una excepción en lugar de devolver un resultado, ¡pero dejaron el método allí para compatibilidad con versiones anteriores! – Yishai

+0

Baring 'destroy' todos los otros métodos de subproceso obsoletos tienen ciertos usos, incl. pausa/reanudar y detener siempre ha sido útil, aunque muy desaconsejado. – bestsss

3

Hay muchos ejemplos en la biblioteca estándar

  • java.awt.Color tiene las mismas constantes con nombres en mayúsculas y minúsculas
  • Todos los métodos en desuso en java.util.Date dadas la introducción de java.util.Calendar - ¡qué desastre!
  • java.util.Enumeration sigue siendo utilizado en java.util.Iterator podría reemplazarlo
  • Clases de oscilación que aceptan vectores como argumentos, pero podría haber tenido el apoyo añadido para java.util.Collection
Cuestiones relacionadas