На этом шаге мы поговорим про то, как виртуальная машина понимает обобщенный код
Виртуальная машина не имеет дела с объектами обобщенных типов - все объекты принадлежат обычным классам. Всякий раз, когда определяется обобщенный тип, автоматически создается соответствующий ему базовый тип. Если T - неограниченная переменная типа, то ее тип просто заменяется на Object. Имя этого типа совпадает с именем обобщенного типа с удаленными типами. Переменные типа стираются и заменяются ограничивающими типами. Например, базовый тип для обобщенного типа Pair<T> выглядит следующим образом:
public class Pair { private Object first; private Object second; public Pair() { this.first = null; this.second = null; } public Pair(Object first, Object second) { this.first = first; this.second = second; } public Object getFirst() { return first; } public void setFirst(Object first) { this.first = first; } public Object getSecond() { return second; } public void setSecond(Object second) { this.second = second; } }
Предположим, что переменная типа имеет несколько ограничений:
class Intervalimplements Serializable { private T lower; private T upper; public Interval(T lower, T upper) { this.lower = lower; this.upper = upper; if (lower.compareTo(upper) > 0) { this.lower = upper; this.upper = lower; } } }
Тогда ему будет соответствовать следующий базовый тип:
class Interval implements Serializable { private Comparable lower; private Comparable upper; public Interval(Comparable lower, Comparable upper) { this.lower = lower; this.upper = upper; if (lower.compareTo(upper) > 0) { this.lower = upper; this.upper = lower; } } }
Заметим, что если мы поменяем местами ограничения, то в этом случае базовый тип заменит обобщенный T на Serializable, а компилятор произведет там, где требуется, приведение к типу Comparable. Поэтому ради эффективности в конце списка ограничений следует размещать интерфейсы, которые не содержат методов.
На следующем шаге мы поговорим про преобразование обобщенных выражений и методов