Нужна помощь в понимании Java учебник по Generics - PullRequest
0 голосов
/ 23 января 2019

Я читал учебник по Java с здесь . У меня проблемы с пониманием простой строки.

В учебнике сказано, что объявление Collections.emptyList:

static <T> List<T> emptyList();

Таким образом, если мы напишем List<String> listOne = Collections.emptyList();, он работает, поскольку компилятор Java может вывести параметр типа, поскольку возвращаемое значение должно иметь тип List<String>.

Теперь рассмотрим метод: void processStringList(List<String> stringList). Теперь говорится:

processStringList (Collections.emptyList ()); Компилятор Java SE 7 генерирует сообщение об ошибке, подобное следующему:

Список <'Объект> не может быть преобразован в Список <' String>

Компилятор требует значение для аргумента типа T, поэтому оно начинается со значения Object. Следовательно, вызов Collections.emptyList возвращает значение типа List<Object>, что несовместимо с методом processStringList

Теперь, что они подразумевают под: , поэтому он начинается со значения Object ? Я имею в виду начать делать что?

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Заявление

processStringList(Collections.emptyList());

отлично работает в Java 8 (я предполагаю, что и выше 8). Компилятор в этом случае достаточно умен, чтобы вывести типы, проверив, какой тип аргумента ожидается для метода.

В более старых версиях, когда компилятор не видит явного возвращаемого типа (как в List<String> listOne = Collections.emptyList();), он по умолчанию выводит <T> в java.lang.Object. Но обратите внимание, что List<Object> и List<String> не совместимы.

Вы можете объявить метод как void processString(List<? super String> list), чтобы избежать ошибки.

0 голосов
/ 23 января 2019

В основном это о возможностях компилятора.Другими словами: в некоторой степени «количество» возможного вывода типа является деталью реализации.

В Java 7 иногда требуется использовать помощники типов / подсказки / свидетели, куда бы вы ни пошли Collections.<String>emptyList() сообщить компилятору об этой недостающей части.

Более поздние реализации компилятора улучшили ситуацию, с которой вы почти всегда можете пойти с Collections.emptyList().

Относительно The compiler requires a value for the type argument T so it starts with the value Object. ... то естьна самом деле довольно просто: компилятор Java должен реализовать алгоритм, который, в конечном итоге, выводит определенный тип.Предоставляя некоторый псевдокод, который может выглядеть следующим образом:

Class<?> inferType(SomeSyntaxTree construct) {

Я просто использую Class здесь, чтобы указать, что алгоритм вернет что-то, что напоминает известный тип.Теперь этот метод может быть реализован следующим образом:

 Class<?> inferedType = Object.class
 while (whatever) {
   refine inferedType
 }
 return inferedType

Другими словами: это очень распространенный подход, когда вы «ищете» какое-то значение: вы инициализируете «наиболее"универсальное значение" (в системе типов Java это будет Object.class), и затем вы увидите, можно ли уточнить это универсальное значение, применяя какой-либо алгоритм.

В нашем случае уточнение может привести к тому, что «наиболее конкретный тип, который можно использовать - это String», но если дальнейшее уточнение невозможно, то вы получите «исходное значение по умолчанию»., будучи Object.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...