Изменения

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

Generics

4869 байт добавлено, 00:59, 2 сентября 2013
Новая страница: «== Generics == Основным мотивом введения Generics в Java было неудобство работы с нетипизированными ...»
== Generics ==
Основным мотивом введения Generics в Java было неудобство работы с нетипизированными коллекциями. Использование нетипизированных коллекций приводит к большим трудозатратам, нежели типизированных, причем может порождать ошибки. Эти ошибки обнаруживаются только во время исполнения. Можно каждый раз, когда требуется коллекция, создавать ее типизированный вариант. Это избавляет от проблем, связанных с применением коллекций, но приводит к большому объему дублированию кода, создаваемого с помощью печально известной технологии copy-paste. Generic-и позволяют избежать подобных проблем за счет введения специальных параметров типов и обобщения реализации классов и методов. Они позволяют не создавать отдельную копию типизированной коллекции с измененным типом элемента, а создать единую обобщенную реализацию, в которой тип элемента заменен параметром типа, и впоследствии переложить работу по созданию специализированных коллекций на компилятор.

== Свойства ==
* Строгая типизация
* Единая реализация
* Отсутствие информации о типе

== Пример реализации Generic-класса ==

public interface List<E> extends Collection<E> {
E get(int i);
set(int i, E e);
add(E e);

Iterator<E> iterator();

}

Теперь рассмотрим чем старая реализация кода отличается от новой :

List<E> ─ список элементов E

'''Раньше''' :

List list = new List();
list.add(new Integer(1));
Integer i = (Integer) list.get(0);

'''Теперь''' :

List<Integer> list = new List<Integer>();
list.add(new Integer(1));
Integer i = list.get(0);

Как видите, больше не нужно приводить Integer, так как метод get() возвращает ссылку на объект конкретного типа (в данном случае – Integer).

== Несовместимость generic-типов ==

Generic-типы не совместимы по присваиванию
List<Integer> li = new ArrayList<Integer>();
List<Object> lo = li;

Иначе — ошибки
lo.add(“hello”);
// ClassCastException
Integer li = lo.get(0);

== Проблемы реализации Generics ==

* Решение 1 - '''Wildcard'''
'''Проблема'''

void dump(Collection<Object> c) {
for (Iterator<Object> i = c.iterator(); i.hasNext(); ) {
Object o = i.next();
System.out.println(o);
}
}

List<Object> l; dump(l);
List<Integer> l; dump(l); // '''Ошибка'''

'''Решение'''
void dump(Collection<?> c) {
for (Iterator<?> i = c.iterator(); i.hasNext(); ) {
Object o = i.next();
System.out.println(o);
}
}

* Решение 2 – '''Bounded Wildcard'''
'''Проблема'''

void draw(List<Shape> c) {
for (Iterator<Shape> i = c.iterator(); i.hasNext(); ) {
Shape s = i.next();
s.draw();
}
}

List<Shape> l; draw(l);
List<Circle> l; draw(l); // '''Ошибка'''

'''Решение'''

void draw(List<? extends Shape> c) {
for (Iterator<? extends Shape> i = c.iterator();
i.hasNext(); ) {
Shape s = i.next();
s.draw();
}
}

* Решение 3 – '''Generic-Метод'''

'''Проблема'''
void addAll(Object[] a, Collection<?> c) {
for (int i = 0; i < a.length; i++) {
c.add(a[i]);
}
}

addAll(new String[10], new ArrayList<String>());
addAll(new Object[10], new ArrayList<Object>());
addAll(new Object[10], new ArrayList<String>()); // '''Ошибка'''
addAll(new String[10], new ArrayList<Object>()); // '''Ошибка'''

'''Решение'''
<T> void addAll(T[] a, Collection<T> c) {
for (int i = 0; i < a.length; i++) {
c.add(a[i]);
}
}
Но все равно после выполнение останется ошибка в третей строчке :
addAll(new Object[10], new ArrayList<String>()); // '''Ошибка'''
16
правок

Навигация