Bridge-методы java

111
09 апреля 2021, 07:10

Прочёл в литературе, что в процессе Type Erasure (стирания типов) компилятор выполняет следующие действия:

  1. добавляет приведение типов для обеспечения type safety, если это необходимо.

  2. генерирует Bridge-методы для сохранения полиморфизма.

Объясните, что из себя представляют "Bridge-методы"?

Answer 1

Возьмём для примера такой код

class Node<T> {
    public T data;
    public Node(T data) { this.data = data; }
    public void setData(T data) {
        System.out.println("Node.setData");
        this.data = data;
    }
}
class MyNode extends Node<Integer> {
    public MyNode(Integer data) { super(data); }
    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }
}
public class Example {
    public static void main(String[] args) {
        MyNode mn = new MyNode(5);
        Node n = mn;
        n.setData("Hello");     
        Integer x = mn.data;
    }
}

После стирания типов выглядеть он будет так

public class Node {
    public Object data;
    public Node(Object data) { this.data = data; }
    public void setData(Object data) {
        System.out.println("Node.setData");
        this.data = data;
    }
}
public class MyNode extends Node {
    public MyNode(Integer data) { super(data); }
    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }
}
public class Example {
    public static void main(String[] args) {
        MyNode mn = new MyNode(5);
        Node n = (MyNode) mn;
        n.setData("Hello");
        Integer x = (String) mn.data;
    }
}

Можно заметить, что после стирания типов сигнатуры метода setData в MyNode и Node больше не совпадают, а значит субкласс не переопределяет метод и полиморфизм оказывается сломан. Чтобы исправить эту ситуацию, компилятор генерирует для MyNode bridge-метод такого вида

public void setData(Object data) {
    setData((Integer) data);
}

Увидеть его можно, заглянуть в байткод с помощью команды javap -c -v MyNode

  public void setData(java.lang.Object);
    descriptor: (Ljava/lang/Object;)V
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: checkcast     #6                  // class java/lang/Integer
         5: invokevirtual #7                  // Method setData:(Ljava/lang/Integer;)V
         8: return

Соответствующий раздел документации.

READ ALSO
Цепные и соединительные потоки

Цепные и соединительные потоки

Насколько я понимаю:

90
Подсказка в intellij idea

Подсказка в intellij idea

Подскажите пожалуйста, как настроить в intellij idea такие же подсказки как в Eclipse?

111
Как перенести настройки IntelliJ IDEA?

Как перенести настройки IntelliJ IDEA?

Как перенести настройки IntelliJ IDEA или же при переустановке системы сделать резервное сохранение настроек программы?

82
Версии Java: платные - не платные, что вообще происходит?

Версии Java: платные - не платные, что вообще происходит?

Если я разрабатываю на Spring MVC web приложение, какую версию Java мне взять, для проекта, который планируется запустить в интернет с целью заработка...

88