Это использование дженериков. Проверьте это вступление . И затем не забудьте прочитать этот учебник .
Далее следует выдержка (которая сравнивает использование приведения с использованием дженериков):
Когда вы видите код , прочитайте его
как «Типа»; декларация выше
читается как «Коллекция строк c.»
код с использованием дженериков яснее и
безопаснее. Мы устранили небезопасные
актерский состав и ряд дополнительных
скобки. Что еще более важно, у нас есть
переехал часть спецификации из
метод из комментария к его
подпись, чтобы компилятор мог проверить
во время компиляции, что тип
ограничения не нарушаются при запуске
время. Потому что программа компилируется
без предупреждения, мы можем заявить с
уверенность, что это не бросит
ClassCastException во время выполнения.
чистый эффект от использования дженериков,
особенно в больших программах, это
улучшенная читаемость и надежность.
Например, интерфейс списка
public interface List<E> {
void add(E x);
Iterator<E> iterator();
}
Это означает, что вы можете создать список, все содержимое которого имеет один и тот же явный тип (не только тип Object), даже если вы определили тип самостоятельно. Итак, если вы создаете класс Name, вы можете написать
List<Name> nameList = new ArrayList<>();
, а затем заполните его экземплярами Name и напрямую извлекайте из него экземпляры Name, не вызывая и не беспокоясь о нем, потому что вы всегда получите либо экземпляр Name, либо нулевой ответ, а не экземпляр другого типа.
Что еще более важно, вы не можете вставить что-либо, отличное от экземпляра Name, в такой список, потому что он потерпит неудачу во время компиляции.
nameList.add(false); //Fails!
nameList.add(new Name("John","Smith")); //Succeeds supposing Name has a
//firstName, lastName constructor