programacion operador genericos generica diamante java generics java-7 java-8 type-inference

genericos - operador diamante java



La inferencia de tipo genérico no funciona con el encadenamiento de métodos? (1)

Por qué ?

Porque la inferencia de tipos de tipos genéricos no se ha expandido a la invocación encadenada.

Del tutorial de java sobre la inferencia de tipos genéricos :

La noción de qué es un tipo de destino se ha ampliado para incluir argumentos de método.

Es por eso que este código:

f(Map.empty());

compila

Pero este código no lo hace porque esta es una invocación encadenada:

f(Map.empty().put(1,"A").put(2,"B"));

También puede encontrar un pequeño párrafo en JSR-000335 Lambda Expressions para JavaTM Programming Language Versión final para evaluación (específicamente parte D):

Ha habido cierto interés en permitir la inferencia de "cadena": en a (). B (), pasar información de tipo desde la invocación de b hasta la invocación de a. Esto agrega otra dimensión a la complejidad del algoritmo de inferencia, ya que la información parcial tiene que pasar en ambas direcciones; solo funciona cuando la eliminación del tipo de retorno de a () se fija para todas las instancias (por ejemplo, Lista). Esta característica no encajaría muy bien en el modelo de expresión de poli, ya que el tipo de destino no puede derivarse fácilmente; pero quizás con mejoras adicionales podría agregarse en el futuro.

Entonces tal vez en Java 9.

Este código se compila en Java 8 pero no se puede compilar en Java 7:

class Map<K,V> { static <K,V> Map<K,V> empty() {return null;} Map<K,V> put(K k, V v) {return null;} V get(K k) {return null;} } class A { static void f(Map<Integer,String> m){} public static void main(String[] args) { f(Map.empty()); } }

No infiere el tipo concreto del Map se devuelve de Map.empty() :

$ javac7 A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty()); ^ required: Map<Integer,String> found: Map<Object,Object> reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion 1 error

Se compila si cambia la llamada f a f(Map.<Integer,String>empty()); . En Java 8, funciona sin tener que recurrir a esto.

Pero si cambia la llamada f a f(Map.empty().put(1,"A").put(2,"B")); , no compila una vez más, tanto en Java 7 como en 8. ¿Por qué?

$ $javac7 A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty().put(1,"A").put(2,"B")); ^ required: Map<Integer,String> found: Map<Object,Object> reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion 1 error $ $javac8 A.java A.java:10: error: incompatible types: Map<Object,Object> cannot be converted to Map<Integer,String> f(Map.empty().put(1,"A").put(2,"B")); ^ Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error $ $javac8 -Xdiags:verbose A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty().put(1,"A").put(2,"B")); ^ required: Map<Integer,String> found: Map<Object,Object> reason: argument mismatch; Map<Object,Object> cannot be converted to Map<Integer,String> 1 error