Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Герберт Шилдт. Java 2, v5.0 (Tiger). Новые возм...doc
Скачиваний:
4
Добавлен:
01.03.2025
Размер:
1.21 Mб
Скачать

Методы-подставки

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

Несмотря на то, что методы-подставки, как правило, не должны Вас интересовать, рассмотрим очень поучительную ситуацию (листинг 3.21), в которой генерируется один из них.

Листинг 3.21. Ситуация, порождающая метод-подставку

class Gen<T> {

T ob; // declare an Object of type T

// Pass the constructor a reference to

// an Object of type T.

Gen(T o) {

ob = o;

}

// Return ob.

T getob() {

return ob;

}

}

// A subclass of Gen.

class Gen2 extends Gen<String> {

Gen2(String o) {

super(o);

}

// A String-specific override of getob().

String getob() {

System.out.print("You called String getob(): ");

return ob;

}

}

// Demonstrate a situation that requires a bridge method.

class BridgeDemo {

public static void main(String args[]) {

// Create a Gen2 Object for Strings.

Gen2 strOb2 = new Gen2("Generics Test");

System.out.println(strOb2.getob());

}

}

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

class Gen2 extends Gen<String> {

Более того, в классе Gen2 переопределен приведенный далее метод getob(), в нем задан тип String как тип возвращаемого методом объекта:

// Версия для типа String, переопределяющая метод getob()

String getob() {

System.out.print ("You called String getob(): ");

return ob;

}

Все перечисленные описания вполне корректны. Но из-за стирания информации о настраиваемом типе тип метода getob() будет следующим:

Object getob() {//...

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

class Gen2 extends Gen{

Gen2(Java.lang.String);

Java.lang.String getob();

java.lang.Object getob(); // метод-подставка

}

как видите, в перечне есть и метод-подставка (комментарий добавил автор, а не утилита javap).И последнее замечание о методах-подставках. Обратите внимание на то, что единственное различие между двумя методами getob() — тип возвращаемого ими объекта. Обычно такая ситуация вызывает ошибку, но поскольку она возникла не в Вашем исходном тексте, виртуальная машина Java (JVM) обрабатывает ее корректно, без каких-либо проблем.