2013-11-21 2 views
3

Пожалуйста, почему я должен поставлять класс Generic с левой стороны (объявление переменной) и правую часть (назначение объекта)? Я могу технически пропустить его влево или вправо (см. Alist2 или aList2), что является недостатком aList2 и aList3 по сравнению с aList1?Использование Java Generics

ArrayList<String> aList1 = new ArrayList<String>(); 
ArrayList<String> aList2 = new ArrayList(); 
ArrayList   aList3 = new ArrayList<String>(); 

Bonus вопрос, просто пришло мне в голову, и он собирает, но то, что это будет означать для aList4 и aList5?

ArrayList<String> aList4 = new ArrayList<>(); 
ArrayList<?>  aList5 = new ArrayList<String>(); 

Заранее спасибо.

С наилучшими пожеланиями, Герман

+0

Далеко не полный ответ, но aList3 не было бы очень полезно для дженериков класса вы спроектировали. Допустим, у вас был 'ArrayList ' С помощью aList3 вам нужно было бы отбросить любой предмет из него в автомобиль. И наоборот, без дженериков справа вы добавляете вещи как объекты, которые являются технически обоснованными, но вы не хотели бы добавлять объект типа 'Car' в ArrayList, предназначенный для хранения объектов типа' Person' – Compass

ответ

1

Первый список является стандартной версии для объявления для Java 6 и более ранних версий, чтобы избежать захвата сырьевых видов из нового ArrayList. Начиная с Java 7, вы можете использовать второй список так же безопасно.

Я не уверен, что третий список безопасен в Java 7, но я бы предположил, что он либо будет хранить все как объекты в любом случае (проблемы с исходными типами), либо даже не может компилироваться.

Четвертый список по существу эквивалентен второму списку, а пятый список эквивалентен третьему списку.

Редактировать: только что протестирован, третий список возвращает необработанные типы, поэтому я бы посоветовал это сделать. Я также пропустил, что во втором списке отсутствует оператор бриллианта в объявлении new ArrayList (который у вас должен быть).

+1

* С Java 7 вы можете использовать второй список так же безопасно * вы имеете в виду 'aList4', а не' aList2'. –

+0

Ах да, я пропустил отсутствие алмазного оператора там, один момент. – Rogue

+0

Обратите внимание, что второй список 'aList2' компилируется с предупреждением с Java 5. –

3

ArrayList является необработанным. Java Spec says о них:

Использование типов raw допускается только в качестве уступки совместимости устаревшего кода. Использование необработанных типов в коде, написанном после введения дженериков в язык программирования Java, настоятельно не рекомендуется. Возможно, что будущие версии языка программирования Java будут запрещать использование необработанных типов.

ArrayList<?> является подстановочным типом, в частности супертипом всех ArrayLists, независимо от их параметра типа. Поскольку мы не знаем тип элементов в Списке, вы можете делать меньше с ним, чем с обычным ArrayList. Например, вы не можете добавить к нему ничего, кроме null, и каждый, что вы берете из списка, известен только как Object.

ArrayList<> является сокращенным обозначением для ArrayList<X>, где X заменяется параметром типа в левой части задания. То есть ArrayList<String> list = new ArrayList<>() полностью эквивалентен ArrayList<String> list = new ArrayList<String>(). Алмазный оператор существует только в Java 7 и выше и может использоваться только в тех местах, где компилятор достаточно умен, чтобы вывести тип, но в этих ситуациях обычно наиболее правильный и согласованный способ использования дженериков.

0

Вы должны использовать класс Generic, который лучше всего подходит для вашей реализации. То есть, если вы заботитесь только о коллекции предметов, вы должны использовать Collection, если вам нужно сохранить заказ, вы должны использовать интерфейс List.Причина этого заключается в том, что вы должны:

Программа интерфейса не реализация GoF

Почему это хорошо? Ну, потому что это упрощает изменение реализации. Предположим, что вы захотите перейти от ArrayList к LinkedList в будущем. Тогда это просто вопрос смены звонка на new ArrayList на new LinkedList. То же самое касается вашего собственного кода, старайтесь всегда использовать интерфейс для любого класса, который не просто объект данных. Это заставит вас задуматься о интерфейсах между вашими объектами, а не о реализации, таким образом вы всегда можете сначала кодовое что-то дерьмовое, а затем уточните свою реализацию всякий раз, когда найдете, что вам нужно, не нарушая ваш код.

article for more info

Так почему это плохо, чтобы не определить тип к вашим примерам? Ну, в основном потому, что программа не будет знать, какие типы содержит список, а это означает, что либо вам нужно подвергать эти объекты их типу, зная тип, либо выясняя тип.

А почему aList2 плохо я не буду просто сослаться на этот discussion

Смежные вопросы