2010-11-04 20 views
13

He descubierto que se puede llamar un método genérico con un tipo especial, por ejemplo:¿Cómo puedo llamar a un método genérico con un tipo cuando se importa estáticamente?

supongamos que tenemos un método genérico:

class ListUtils { 
    public static <T> List<T> createList() { 
     return new ArrayList<T>(); 
    } 
} 

podemos llamar así:

List<Integer> intList = ListUtils.<Integer>createList(); 

Pero ¿cómo podemos llamarlo cuando se importa estáticamente? e.g .:

List<Integer> intList = <Integer>createList(); 

Esto no funciona.

+0

¿No funciona la inferencia para su ejemplo concreto? – Roman

+0

posible duplicado de [Invocar método importado estáticamente con parámetros de tipo explícito] (http://stackoverflow.com/questions/2050317/invoking-statically-imported-method-with-explicit-type-parameters) –

+0

Posible duplicado de [Invocar estáticamente método importado con parámetros de tipos explícitos] (https://stackoverflow.com/questions/2050317/invoking-statically-imported-method-with-explicit-type-parameters) –

Respuesta

9

No puede. Tendría que hacer referencia usando el nombre de la clase.

Parece que tener:

void foo(List<String> a) {} 

y llamando foo(createList()) no infiere del tipo correcto. Por lo que debe utilizar, ya sea de forma explícita el nombre de la clase, como ListUtils.createList() o utilizar una variable intermedia:

List<String> fooList = createList(); 
foo(fooList); 

Por último, guava tiene Lists.newArrayList(), así que será mejor que volver a utilizar.

+0

¡Gracias! Ni siquiera pensé en esa situación (llame al sitio del parámetro). Y solo me inclino por la guayaba, ¡es genial! –

2

Los siguientes obras para mí:

package test; 
import java.util.List; 
import static test.ListUtils.createList; 

public class ListConsumer { 
    public static void main(String[] args) { 
     List<Integer> list = createList(); 
     List<String> list2 = createList(); 
    } 
} 
+0

Gracias por la aclaración :) No entendí completamente la inferencia del tipo entonces. –

1

creo Mindas ya ha demostrado que esto debería funcionar con la inferencia, la sintaxis es un poco fuera. Sin embargo, recomendaría que eche un vistazo a Google Guava, tienen este método exacto y muchos otros útiles disponibles. No tiene sentido reinventar la rueda :)

2

No puedes. Esta es una falla de diseño en la sintaxis del lenguaje Java. Scala, que es un lenguaje tipado estáticamente más nuevo en JVM, corrige esto. (Así es como harías esa llamada en Scala: val intList: List[Int] = creatList[Int]()).

0

Por lo que he leído, una deficiencia del mecanismo de importación estática es que debe especificar el objeto/clase que realiza la llamada si desea proporcionar parámetros formales. Mindas es correcto, cuando no hay argumentos, el mecanismo de inferencia de tipo usará el tipo al que se le asigna el valor de retorno de la función. El truco viene cuando estás proporcionando argumentos sin embargo. Si desea evitar tener que especificar el objeto/clase llamando puede escribir pista a través de un elenco de los argumentos como tal:

public static <E> E foo(E e) {} 

Number n = foo((Number)3); 

Con la indirecta tipo, el tipo de inferencia devolverá un objeto de tipo Number, en vez de Entero como lo habría razonado de otra manera.

Cuestiones relacionadas