Влияние тройного оператора 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()
...
Ответы
Ответ 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 понятие того, что является типом цели, было расширено, чтобы включить аргументы метода. Так что это больше не требуется.