Вызов статических универсальных методов

106

Я столкнулся с любопытной ситуацией, связанной со статическими универсальными методами. Это код:

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

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

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

Почему мне не нужно указывать аргументы типа в выражении Foo.createFoo()? Это что-то вроде вывода типа? Если я хочу четко указать на это, как я могу указать аргумент типа?

fredoverflow
источник
7
Я бы порекомендовал вам изменить параметр типа E метода createFoo. Поскольку параметр типа E класса Foo отличается от параметра типа E метода createFoo ().
Gursel Koca
@GurselKoca Он мог явно сделать member = Foo. <E> createFoo (); требуя, чтобы они были такими же, как время компиляции.
Джордж Ксавье

Ответы:

183

Да, это вывод типа на основе цели назначения, согласно разделу 15.12.2.8 JLS . Чтобы быть точным, вы бы назвали что-то вроде:

Foo.<String>createFoo();
Джон Скит
источник
3
Или, как в моем случае: Foo.<E>createFoo();Спасибо :)
fredoverflow
7
Почему это тоже работает без задания? То есть инструкция Foo.createFoo(); компилируется нормально ...? Это из-за стирания типа?
fredoverflow
9
@FredOverflow без присваивания E«предполагается»Object
неоспоримо
2
Новое местоположение ссылки, вероятно , будет: docs.oracle.com/javase/specs/jls/se8/html/...
Joanis
3
Другой способ указать тип - Eэто определить, createFoo()принять аргумент типа Class<E>(так оно и было createFoo(Class<E> type)), и вызвать его с помощьюcreateFoo(String.class)
Гэвин С. Янси