Изменения

Перейти к: навигация, поиск

Generics

83 байта добавлено, 21:49, 1 октября 2013
Нет описания правки
Наиболее распространенными примерами являются Коллекции.
Вот типичное использование такого рода(без Generics):
List myIntList = new LinkedList(); // 1
Он указывает на то, что это не просто произвольный List, а List<Integer>.
Мы говорим, что List является generic-интерфейсом, который принимает параметр типа - в этом случае, Integer.
Кроме того, необходимо обратить внимание на то, что каст Cast выполняется по линии 3' автоматически.
Некоторые могут задуматься, что беспорядок в коде увеличился, но это не так.
То G<Foo> '''не является''' наследником G<Bar>.
* '''Пример''':
List<Integer> li = new ArrayList<Integer>();
List<Object> lo = li;
Пусть мы захотели написать метод, который берет Collection<Object> и выводит на экран. И мы захотели вызвать dump для Integer.
* '''Проблема'''
void dump(Collection<Object> c) {
List<Object> l; dump(l);
List<Integer> l; dump(l); // '''Ошибка'''
 
В этом примере List<Integer> не может использовать метод dump, так как он не является подтипом List<Object>.
Проблема в том что эта реализация кода не эффективна, так как Collection<Object> не является полностью родительской коллекцией всех остальных коллекции, грубо говоря Collection<Object> имеет ограничения.
Для решения этой проблемы используется Wildcard ("?"). Он не имеет ограничения в использовании(то есть имеет соответствие с любым типом) и в этом его плюсы. И теперь, мы можем назвать это с любым типом коллекции.
В этом примере List<Integer> не может использовать метод dump, так как он не является подтипом List<Object>.  * '''Решение'''
void dump(Collection<?> c) {
for (Iterator<?> i = c.iterator(); i.hasNext(); ) {
* Решение 2 – '''Bounded Wildcard'''
Пусть мы захотели написать метод, который рисует List<Shape>. И у Shape есть наследник Circle.
И мы хотим вызвать draw для Circle. Но у нас не получиться из-за несовместимости типов.
* '''Проблема'''
void draw(List<Shape> c) {
List<Circle> l; draw(l); // '''Ошибка'''
Это Проблема в том, что у нас не получиться из-за несовместимости типов.Предложенное решение используютиспользуется, если метод который нужно реализовать использовал бы определенный тип и его подтипов. Так называемое "Ограничение сверху". Для этого нужно вместо <Shape> прописать <? extends Shape>.
* '''Решение'''
void draw(List<? extends Shape> c) {
Пусть вы захотели сделать метод, который берет массив Object и переносить их в коллекцию.
* '''Проблема'''
void addAll(Object[] a, Collection<?> c) {
for (int i = 0; i < a.length; i++) {
Напомним, что вы не можете просто засунуть Object в коллекции неизвестного типа. Способ решения этой проблемы является использование "Generic-Метод" Для этого перед методом нужно объявить <T> и использовать его.
* '''Решение'''
<T> void addAll(T[] a, Collection<T> c) {
for (int i = 0; i < a.length; i++) {
Анонимный участник

Навигация