2012-04-19 18 views
7

Supongamos que tengo un método tan simple como este para el procesamiento de dos listas:genéricos de Java: inferir tipos más de dos parámetros

public static <B> void foo(List<B> list1, List<B> list2) { 
} 

Y supongamos que quiero llamarlo así:

foo(ImmutableList.of(), ImmutableList.of(1)); 

Este won 'compilar, porque javac no es lo suficientemente inteligente como para descubrir que estaba tratando de crear dos listas de enteros. En su lugar, tengo que escribir:

foo(ImmutableList.<Integer>of(), ImmutableList.of(1)); 

¿Cómo debo cambiar la declaración de foo para permitir que la primera versión que funciona tan bien como el segundo?

+1

Bastante seguro que no se puede hacer cambiando la declaración de 'foo()'. –

+0

En realidad, no es una cuestión de 'javac' no ser lo suficientemente inteligente, es una pregunta genuina de lo que quiere decir con' ImmutableList.of() '. ¿Qué pasa si 'of()' devuelve no una lista vacía sino una lista llena de 5 objetos creados con constructores por defecto? Son solo las partes internas de 'of()' las que le dicen que ese no es el caso, y si eso es lo que pasó, 'foo' obtendría una lista de' Object's y una lista de 'Integer's. –

Respuesta

3

Estoy bastante seguro de que la inferencia del tipo de Java no es lo suficientemente potente como para manejar la unificación.

Lo que podría hacer es devolver un objeto intermedio de algún tipo, y cambiar el sitio de llamada a ser algo así como:

foo(list1).and(list2) 

Pero entonces todavía sólo sería capaz de inferir de izquierda a derecha, por lo que tendría que llamar como:

foo(ImmutableList.of(1)).and(ImmutableList.of()); 
1

usted puede hacer eso con sólo cambiar información genérica del parametro y ambas versiones se work.ie

public static <B> void foo(List<? super B> list1, List<B> list2) { 


     } 

Ahora Ambas versiones funcionarán.

foo(ImmutableList.of(), ImmutableList.of(1)); 
foo(ImmutableList.<Integer>of(), ImmutableList.of(1)); 
+1

Esta no es una gran opción si 'foo' en realidad lee' B's de 'list1'. – trutheality

2

El único ajuste en el que veo que esto es un inconveniente para usted es cuando hace esto mucho. En ese caso, se puede hacer una

private static final ImmutableList<Integer> EMPTYINTLIST = ImmutableList.<Integer>of(); 

y usar su EMPTYINTLIST en sus llamadas.

Cuestiones relacionadas