Подтвердить что ты не робот

Влияние тройного оператора Java на вывод типа дженериков

public List<String> foo1() {
    List<String> retval = bar();
    if (retval == null)
        return Collections.emptyList();
    else
        return retval;
}

public List<String> foo2() {
    List<String> retval = bar();
    return retval == null ? Collections.emptyList() : retval;
}

Почему foo1() компилируется в то время как foo2() имеет ошибку? (точнее "несоответствие типов": невозможно преобразовать из List < capture # 1-of? extends Object > to List <String> ")

Я бы подумал, что обе функции будут компилироваться в один и тот же байт-код, поэтому умный компилятор должен вывести правильный тип для emptyList()...

4b9b3361

Ответ 1

Скомпилирует для меня штраф в java 8.

Более ранние версии Java могут нуждаться в дополнительной помощи

return retval == null ? Collections.<String>emptyList() : retval;

должен работать.

ИЗМЕНИТЬ Это связано с улучшением вывода типа Java 8, как описано здесь.

http://openjdk.java.net/jeps/101

И вот блог с основными моментами: http://blog.jooq.org/2013/11/25/a-lesser-known-java-8-feature-generalized-target-type-inference/

Ответ 2

Это связано с типом вывода из общего метода.

В случае кода перед ver. 8. Он должен быть объявлен типом результата для этого случая.

return retval == null ? Collections.<String>emptyList() : retval;

Так как ver. 8 понятие того, что является типом цели, было расширено, чтобы включить аргументы метода. Так что это больше не требуется.