Являются ли дженерики Java главным образом способом навязывания статического типа элементам коллекции? - PullRequest
5 голосов
/ 20 апреля 2009
private ArrayList<String> colors = new ArrayList<String>();

Глядя на приведенный выше пример, кажется, что основной смысл обобщений заключается в принудительном применении типа к коллекции. Таким образом, вместо того, чтобы иметь массив «Объектов», которые должны быть преобразованы в String по усмотрению программиста, я использую тип «String» в коллекции в ArrayList. Это ново для меня, но я просто хочу проверить, правильно ли я это понимаю. Правильно ли это толкование?

Ответы [ 8 ]

8 голосов
/ 20 апреля 2009

Это далеко не только использование дженериков, но это определенно самый заметный.

Обобщения могут использоваться (и используются) во многих местах для обеспечения безопасности статического типа, а не только для коллекций.

Я просто хотел бы упомянуть об этом, потому что вы встретите места, где дженерики могут быть полезны, но если вы застряли в ассоциации дженериков / коллекций, вы можете пропустить этот факт.

2 голосов
/ 20 апреля 2009

Да, ваше понимание верно. Коллекция строго типизирована к любому указанному типу, что имеет различные преимущества, в том числе не приводит к приведению во время выполнения.

1 голос
/ 20 апреля 2009

Да, вот и все. Прежде чем генерики, нужно было создать ArrayList объектов. Это означало, что можно добавить в список любой тип объекта - даже если вы только хотели, чтобы ArrayList содержал строки.

Все генерики - это добавление безопасности типов. То есть теперь JVM будет проверять, что любой объект в списке является строкой, и не позволит вам добавить объект, не являющийся строкой, в список. Еще лучше: эта проверка выполняется во время компиляции.

1 голос
/ 20 апреля 2009

Да. Для обеспечения безопасности типов и удаления приведений во время выполнения правильный ответ.

0 голосов
/ 20 апреля 2009

Вы можете использовать универсальный в любом месте, где вам нужен параметр типа , то есть тип, который должен быть одинаковым в некотором коде, но в большей или меньшей степени не указан.

Например, один из моих игрушечных проектов - написать алгоритмы для компьютерной алгебры в Java. Это интересно как для математических алгоритмов, так и для того, чтобы подвергать дженерики Java стресс-тесту.

В этом проекте у меня есть различные интерфейсы для алгебраических структур, таких как кольца и поля и их соответствующие элементы, и конкретные классы, например. для целых чисел или для многочленов над кольцом, где кольцо является параметром типа. Это работает, но местами становится несколько утомительно. До сих пор запись представляет собой тип перед переменной, который охватывает две полные строки по 80 символов в алгоритме проверки неприводимости полиномов. Главный виновник в том, что вы не можете дать сложному типу собственное имя.

0 голосов
/ 20 апреля 2009

Да, вы правы. Generics добавляет безопасность типов во время компиляции в вашу программу, что означает, что компилятор может обнаружить, если вы помещаете неправильный тип объектов в то есть ваш ArrayList.

Одна вещь, на которую я хотел бы обратить внимание, заключается в том, что, хотя она удаляет видимое приведение во время выполнения и снимает загромождение исходного кода, JVM по-прежнему выполняет приведение в фоновом режиме.

Способ, которым Generics реализован в Java, просто скрывает приведение и по-прежнему создает неуниверсальный байт-код. ArrayList<String> все еще является ArrayList объектов в байт-коде. Хорошая вещь об этом - то, что он поддерживает байт-код совместимым с более ранними версиями. Плохо то, что это упускает огромную возможность оптимизации.

0 голосов
/ 20 апреля 2009

Вы можете добавить проверки во время выполнения с помощью служебного класса Collections.

http://java.sun.com/javase/6/docs/api/java/util/Collections.html#checkedCollection(java.util.Collection,%20java.lang.Class)

Также см. Проверил набор, проверил список, проверил отсортированный набор, проверил карту, проверил отсортированную карту

0 голосов
/ 20 апреля 2009

Вы можете проверить учебник на сайте Java . Это дает хорошее объяснение во введении.

Без обобщения:

List myIntList = new LinkedList(); // 1
myIntList.add(new Integer(0)); // 2
Integer x = (Integer) myIntList.iterator().next();  // 3

с родовыми элементами

List<Integer> myIntList = new LinkedList<Integer>(); // 1'
myIntList.add(new Integer(0)); // 2'
Integer x = myIntList.iterator().next(); // 3'

Я думаю, что это безопасность типов, а также сохранение литья. Узнайте больше о autoboxing .

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