【问题标题】:Bridge method creating桥接方法创建
【发布时间】:2013-10-12 21:57:49
【问题描述】:

我对桥接方法创建有一些疑问。我们可以将桥接技术应用于协变覆盖。现在考虑官方帮助中的示例:

public class Node<T>{
    private T data;
    public Node(T data){ this.data=data;}
    public void setData(T data){
         System.out.println("Node.setData");
         this.data=data;
    }
}
public class MyNode extends Node<Integer>{
    public MyNode(Integer data){ super(data); }
    public void setData(Integer data){
         System.out.println("MyNode.setData");
         this.data=data;
    }
}

让桥接方法不创建。因此在运行时类MyNode 有两个方法:setData(Integer)setData(Object),其中last 继承自Node。当我们调用setData(new Inetegr(5)) 时将调用setData(Integer)。如果我们写Object o= new Integer(5); setData(o);,那么setData(Object) 将被调用。这不是真的。 那么两个问题:

  1. 我是否正确理解引入桥接法的原因?
  2. 建立桥接方法的必要和充分条件是什么?

【问题讨论】:

标签: java generics bridge


【解决方案1】:

我是否正确理解引入桥接方法的原因?

我认为是的。如果编译器没有生成桥方法,那么子类中的方法将是超类方法的重载版本,而不是重载版本。你似乎已经明白了。

建立桥接方法的必要和充分条件是什么?

当您扩展或实现参数化类型时,类型擦除会更改超类中方法的签名。

如果我们写Object o= new Integer(5); setData(o);,那么setData(Object) 将被调用。这不是真的。

我不明白你的意思。您应该在非泛型代码上测试此行为。当方法被重载时,方法调用绑定到哪个方法,在编译时根据您传递的参数的声明类型决定。由于本例中声明的类型为Object,因此会调用setData(Object)版本。

【讨论】:

  • 我不明白你的意思 让我们有原始类型声明Node m= new MyNode(5); Object o= new Integer(5); m.setData(o);。选择虚拟方法的具体实现是在运行时按对象类型确定。但是setData(Object) 方法不会在MyNode 中被覆盖。因此Node的方法将被调用。
  • 当您扩展或实现参数化类型时,类型擦除会更改超类中方法的签名。 但在协变覆盖的情况下,我们可能没有参数化类型。但是桥接方法正在创建。没有其他条件可以创建桥接方法,不是吗?
【解决方案2】:

这是一个应用桥接技术的编译器,而不是我们。在您的情况下,编译器将在此处插入桥:

class MyNode extends Node<Integer> {
  public void setData(Object data) {
     setData((Integer) data);
  }
...

这就是它被使用的原因:

    Node<Integer> n = new MyNode();
    n.setData(1);

节点没有 setData(Integer) 它有 setData(Object)。 MyNode 桥方法 setData(Object) 覆盖它。 JVM 检测到 n 的实际类型是 MyNode 并调用 MyNode.setData(Object) 将重定向到 setData(Integer)。

另一种应用桥接方法的情况是协变返回类型:

class X implements Cloneable {
    @Override
    public X clone() {
         ...
    }

实际上需要bridge 来覆盖Object.clone。请注意,字节码中的方法签名包括返回类型。

【讨论】:

    猜你喜欢
    • 2015-09-14
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 2013-10-02
    • 1970-01-01
    相关资源
    最近更新 更多