Исследование обобщённого программирования
Java Generics
Особенность Java Generics — подчистка типов. Обобщенный класс A<T>
транслируется в обычный класс A
, где везде вместо типа T
используется Object
. Если на параметр типа есть ограничение, например, A<T extends Comparable<T> >
, то в подчищенном коде вместо T
стоит Comparable
.
Из-за подчистки типов возникает неприятное для нас ограничение: параметр шаблона не может реализовывать разные специализации одного интерфейса [*]. Что это и чем оно нам грозит?
Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт
Convertible<S, U>
который содержит функцию
U convert(S x)
или
U S::convert()
Можем ли мы реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?
public interface Convertible<S> {
public S convert();
}
public class A1 {}
public class A implements Convertible<A1> {
public A1 convert() {
return new A1();
}
}
Здорово! Но мы хотим, чтобы класс A
мог быть преобразован и в какой-нибудь A2
.
public interface Convertible<S> {
public S convert();
}
public class A1 {}
public class A2 {}
public class A implements Convertible<A1>, Convertible<A2> {
public A1 convert() {
return new A1();
}
public A2 convert() {
return new A2();
}
}
А вот это уже не работает. Причина — ограничение [*], которое даёт подчистка типов. Класс A
может реализовывать только какой-нибудь один Convertible
.