¿Por qué a los operadores ternarios no les gustan los tipos genéricos con comodines acotados?
La siguiente clase define dos métodos, los cuales intuitivamente tienen la misma funcionalidad. Cada función se llama con dos listas de tipoList<? super Integer>
y un valor booleano que especifica cuál de esas listas debe asignarse a una variable local.
import java.util.List;
class Example {
void chooseList1(boolean choice, List<? super Integer> list1, List<? super Integer> list2) {
List<? super Integer> list;
if (choice)
list = list1;
else
list = list2;
}
void chooseList2(boolean choice, List<? super Integer> list1, List<? super Integer> list2) {
List<? super Integer> list = choice ? list1 : list2;
}
}
De acuerdo ajavac 1.7.0_45
, chooseList1
es válido mientraschooseList2
no es. Se queja:
java: incompatible types
required: java.util.List<? super java.lang.Integer>
found: java.util.List<capture#1 of ? extends java.lang.Object>
Sé que las reglas para encontrar el tipo de expresión que contiene el operador ternario (… ? … : …
) son bastante complejos, pero en la medida en que los entiendo, elige el tipo más específico al que se pueden convertir tanto el segundo como el tercer argumento sin una conversión explícita. Aquí, esto debería serList<? super Integer> list1
pero no lo es
Me gustaría ver una explicación de por qué este no es el caso, preferiblemente con una referencia de laEspecificación del lenguaje Java y una explicación intuitiva de lo que podría salir mal si no se previene.