Wywołanie statycznych metod ogólnych

106

Natknąłem się na ciekawą sytuację związaną ze statycznymi metodami ogólnymi. To jest kod:

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

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

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

Dlaczego nie muszę określać żadnych argumentów typu w wyrażeniu Foo.createFoo()? Czy to jakiś rodzaj wnioskowania o typie? Jeśli chcę to wyraźnie określić, jak mogę określić argument typu?

fredoverflow
źródło
7
Zalecałbym zmianę parametru typu E metody createFoo. Ponieważ parametr typu E klasy Foo jest inny niż parametr typu E metody createFoo ().
Gursel Koca
@GurselKoca Mógłby jawnie zrobić member = Foo. <E> createFoo (); wymagając, aby były takie same jak czas kompilacji.
George Xavier

Odpowiedzi:

183

Tak, jest to wnioskowanie o typie na podstawie celu przypisania, zgodnie z sekcją JLS 15.12.2.8 . Mówiąc wprost, nazwałbyś coś takiego:

Foo.<String>createFoo();
Jon Skeet
źródło
3
Lub, jak w moim przypadku: Foo.<E>createFoo();dziękuję :)
fredoverflow
7
Dlaczego to działa również bez przydziału? Oznacza to, że instrukcja Foo.createFoo(); kompiluje się dobrze ...? Czy jest to spowodowane wymazywaniem typu?
fredoverflow
9
@FredOverflow bez przypisania Ejest „wywnioskowany” jakoObject
bezcenny.
2
Nowa lokalizacja linku to prawdopodobnie: docs.oracle.com/javase/specs/jls/se8/html/…
Joanis,
3
Innym sposobem określenia typu Ebyłoby zdefiniowanie createFoo()weź argument typu Class<E>(tak by było createFoo(Class<E> type)) i wywołanie go za pomocącreateFoo(String.class)
Gavin S. Yancey