Прежде всего: если вы не используете Java 7, все это не будет работать, потому что ромб <>
был представлен только в этой версии Java.
Также,этот ответ предполагает, что читатель понимает основы обобщений .Если вы этого не сделаете, то прочитайте другие части учебного пособия и вернитесь, когда вы поймете это.
Алмаз на самом деле является сокращением для того, чтобы не повторять информацию об общем типе прикомпилятор может определить тип самостоятельно.
Наиболее распространенный вариант использования - это когда переменная определена в той же строке, что и инициализированная:
List<String> list = new ArrayList<>(); // is a shortcut for
List<String> list = new ArrayList<String>();
В этом примере разница неЭто не главное, но как только вы доберетесь до Map<String, ThreadLocal<Collection<Map<String,String>>>>
, это будет значительное улучшение (примечание: я не поощряю использование таких конструкций!).
Проблема в том, что правила заходят так далеко.В приведенном выше примере совершенно очевидно, какой тип следует использовать, и компилятор, и разработчик согласны с этим.
В этой строке:
list.addAll(new ArrayList<>());
это кажется очевидно.По крайней мере, разработчик знает, что тип должен быть String
.
Однако, взглянув на определение Collection.addAll()
, мы увидим тип параметра Collection<? extends E>
.
Это означает, что addAll
принимает любую коллекцию, которая содержит объекты любого неизвестного типа, который расширяет тип нашего list
.Это хорошо, потому что это означает, что вы можете addAll
a List<Integer>
до List<Number>
, но это делает наш вывод типа более сложным.
Фактически это делает вывод типа не работающим в соответствии с правилами, изложенными в настоящее время.по JLS.В некоторых ситуациях можно утверждать, что правила могут быть расширены для работы, но текущие правила подразумевают, что не делают этого.