Recientemente estoy leyendo el código fuente de Spring Framework. Algo que no puedo entender va aquí:
public Member getMember() {
// NOTE: no ternary expression to retain JDK <8 compatibility even when using
// the JDK 8 compiler (potentially selecting java.lang.reflect.Executable
// as common type, with that new base class not available on older JDKs)
if (this.method != null) {
return this.method;
}
else {
return this.constructor;
}
}
Este método es miembro de la clase org.springframework.core.MethodParameter
. El código es fácil de entender mientras que los comentarios son difíciles.
NOTA: no hay expresión ternaria para retener la compatibilidad JDK <8 incluso cuando se usa el compilador JDK 8 (potencialmente seleccionando
java.lang.reflect.Executable
como tipo común, con esa nueva clase base no disponible en JDK más antiguos)
¿Cuál es la diferencia entre usar una expresión ternaria y usar una if...else...
construcción en este contexto?
fuente
Esto se introdujo en un compromiso bastante antiguo el 3 de mayo de 2013, casi un año antes del lanzamiento oficial de JDK-8. El compilador estaba en un gran desarrollo en esos momentos, por lo que podían ocurrir problemas de compatibilidad. Supongo que el equipo de Spring acaba de probar la compilación JDK-8 e intentó solucionar problemas, aunque en realidad son problemas del compilador. Para el lanzamiento oficial de JDK-8, esto se volvió irrelevante. Ahora, el operador ternario en este código funciona bien como se esperaba (no hay ninguna referencia a la
Executable
clase en el archivo .class compilado).Actualmente aparecen cosas similares en JDK-9: algún código que se puede compilar muy bien en JDK-8 falla con JDK-9 javac. Supongo que la mayoría de estos problemas se solucionarán hasta el lanzamiento.
fuente
Executable
, en violación de algún aspecto de la especificación? ¿O es solo que Oracle se dio cuenta de que podían cambiar este comportamiento de una manera que aún se ajustara a las especificaciones y sin romper la compatibilidad con versiones anteriores?Executable
tipos intermedios. En Java-8, el concepto de inferencia de tipos de expresión cambió drásticamente y esta parte se reescribió por completo, por lo que no es tan sorprendente que las primeras implementaciones tuvieran errores.La principal diferencia es que un
if
else
bloque es una declaración, mientras que el ternario (más conocido como operador condicional en Java) es una expresión .Una declaración puede hacer cosas similares
return
a la persona que llama en algunas de las rutas de control. Se puede utilizar una expresión en una tarea:int n = condition ? 3 : 2;
Entonces, las dos expresiones en el ternario después de la condición deben ser coercibles al mismo tipo. Esto puede causar algunos efectos extraños en Java, particularmente con el auto-boxing y la conversión automática de referencias; esto es a lo que se refiere el comentario en su código publicado. La coerción de las expresiones en su caso sería a un
java.lang.reflect.Executable
tipo (ya que ese es el tipo más especializado ) y eso no existe en versiones anteriores de Java.Estilísticamente, debería usar un
if
else
bloque si el código es similar a una declaración y un ternario si es similar a una expresión.Por supuesto, puede hacer que un
if
else
bloque se comporte como una expresión si usa una función lambda.fuente
El tipo de valor de retorno en una expresión ternaria se ve afectado por las clases principales, que cambiaron como se describe en Java 8.
Es difícil ver por qué no se pudo haber escrito un elenco.
fuente