Влияние троичного оператора 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
Я бы подумал, что обе функции будут компилироваться в один и тот же байт-код, поэтому умный компилятор должен вывести правильный тип для emptyList()
...
2 ответа
Компилирует для меня нормально в 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/
Это связано с выводом типа из универсального метода.
В случае кода до вер. 8. Должен быть объявлен тип результата для этого случая.
return retval == null ? Collections.<String>emptyList() : retval;
С вер. 8 понятие того, что является целевым типом, было расширено, чтобы включить аргументы метода. Так что это больше не требуется.