Llamar a métodos genéricos estáticos

106

Me he encontrado con una situación curiosa que involucra métodos genéricos estáticos. Este es el código:

class Foo<E>
{
    public static <E> Foo<E> createFoo()
    {
        // ...
    }
}

class Bar<E>
{
    private Foo<E> member;

    public Bar()
    {
        member = Foo.createFoo();
    }
}

¿Cómo es que no tengo que especificar ningún tipo de argumento en la expresión Foo.createFoo()? ¿Es esto algún tipo de inferencia de tipo? Si quiero ser explícito al respecto, ¿cómo puedo especificar el argumento de tipo?

fredoverflow
fuente
7
Le recomendaría que cambie el parámetro de tipo E del método createFoo. Porque, el parámetro de tipo E de la clase Foo es diferente al parámetro de tipo E del método createFoo ().
Gursel Koca
@GurselKoca Podría hacer explícitamente member = Foo. <E> createFoo (); requiriendo que sean iguales al tiempo de compilación.
George Xavier

Respuestas:

183

Sí, esta es una inferencia de tipo basada en el objetivo de la asignación, según la sección 15.12.2.8 de JLS . Para ser explícito, llamarías a algo como:

Foo.<String>createFoo();
Jon Skeet
fuente
3
O, como en mi caso: Foo.<E>createFoo();Gracias :)
fredoverflow
7
¿Cómo es que esto también funciona sin la asignación? Es decir, ¿la declaración se Foo.createFoo(); compila bien ...? ¿Esto se debe al borrado de tipo?
fredoverflow
9
@FredOverflow sin asignación Ese "infiere" que esObject
irrefutable
2
Nueva ubicación del enlace probablemente sería: docs.oracle.com/javase/specs/jls/se8/html/...
Joanis
3
Una forma diferente de especificar el tipo de Esería definir createFoo()tomar un argumento de tipo Class<E>(así sería createFoo(Class<E> type)) y llamarlo concreateFoo(String.class)
Gavin S. Yancey