Методы-мосты

Иногда компилятору приходится добавлять классу так называемый метод-мост (bridge method), чтобы справиться с ситуациями, когда результат очистки типов в перегруженном методе подкласса не совпадает с тем, что получается при очистке в суперклассе. В этом случае генерируется метод, который использует очистку типов суперкласса, и этот метод вызывает соответствующий метод подкласса, выполняющий очистку. Конечно, методы-мосты появляются только на уровне байт-кода, невидимы для вас и недоступны для непосредственного вызова.

Несмотря на то что методы-мосты — это не то, в чем вы обычно нуждаетесь и с чем имеете дело, все же полезно рассмотреть ситуацию, в которой они генерируются. Взгляните на следующую программу:

// Ситуация, в которой генерируется метод-мост.
class Gen {
Т ob; // объявить объект типа Т
// Передать конструктору ссылку на
// объект типа Т.
Gen(T о) {
ob = о;
}
// Возвращает ob.
Т getob () {
return ob;
}
}
// Подкласс Gen.
class Gen2 extends Gen {
Gen2(String o) {
super(o);
}
// String-ориентированная перегрузка getob().
String getob () {
System.out.print("Вызван String getobO: ");
return ob;
}
}
// Демонстрация ситуации, в которой необходим метод-мост.
class BridgeDemo {
public static void main(String args[]) {
// Создать объект Gen2 для Strings.
Gen2 str0b2 = new Gen2("Обобщенный тест");
System.out.println(strOb2.getob());
}
}

В этой программе Gen2 расширяет Gen, но делает это с использованием специфичной String-версии Gen, как показывает следующее объявление:

class Gen2 extends Gen {

Более того, внутри Gen2 метол getob () переопределен с типом возврата String:

// String-ориентированная перегрузка getob ().
String getob () {
System.out.print("Вызван String getobO: ");
return ob;
}

Все это совершенно допустимо. Единственная проблема в том, что из-за очистки типов ожидаемая форма getob () будет выглядеть так:

Object getob () {
//...

Чтобы справиться с этой проблемой, компилятор генерирует метод-мост с показанной выше сигнатурой, который вызывает String-версию. То есть, если вы посмотрите на интерфейс класса Gen2 с помощью j avap, то увидите следующие методы: class Gen2 extends Gen( Gen2(java.lang.String);
java.lang.String getob();
java.lang.Object getobО;
// метод-мост }

Как видите, сюда включен метод-мост. (Комментарий добавлен автором, а не java.p)

Последнее замечание о методах-мостах. Обратите внимание, что единственная разница между двумя методами getob () заключается в типе возврата. Обычно это вызывает ошибку, но поскольку это происходит не в исходном коде, проблема не возникает и JVM успешно справляется с этой ситуацией.