Appel de méthodes génériques statiques

106

J'ai rencontré une situation curieuse impliquant des méthodes génériques statiques. Voici le code:

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

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

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

Comment se fait-il que je n'ai pas à spécifier d'arguments de type dans l'expression Foo.createFoo()? Est-ce une sorte d'inférence de type? Si je veux être explicite à ce sujet, comment puis-je spécifier l'argument de type?

fredoverflow
la source
7
Je vous recommande de changer le paramètre de type E de la méthode createFoo. Parce que le paramètre de type E de la classe Foo est différent du paramètre de type E de la méthode createFoo ().
Gursel Koca
@GurselKoca Il pourrait explicitement faire membre = Foo. <E> createFoo (); les obligeant à être identiques au moment de la compilation.
George Xavier

Réponses:

183

Oui, il s'agit d'une inférence de type basée sur la cible de l'affectation, conformément à la section JLS 15.12.2.8 . Pour être explicite, vous appelleriez quelque chose comme:

Foo.<String>createFoo();
Jon Skeet
la source
3
Ou, comme dans mon cas: Foo.<E>createFoo();Merci :)
fredoverflow
7
Comment cela fonctionne-t-il également sans la cession? Autrement dit, la déclaration Foo.createFoo(); compile très bien ...? Est-ce dû à un effacement de type?
fredoverflow
9
@FredOverflow sans affectation Eest "déduit" d'êtreObject
irréputable
2
Le nouvel emplacement du lien serait probablement: docs.oracle.com/javase/specs/jls/se8/html/…
Joanis
3
Une autre façon de spécifier le type de Eserait de définir createFoo()prendre un argument de type Class<E>(ce serait le cas createFoo(Class<E> type)), et de l'appeler aveccreateFoo(String.class)
Gavin S. Yancey