我有一些关于桥方法创建的问题。我们可以将桥技术应用于协变覆盖。现在考虑官方帮助中的例子:
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),最后一个是从Node继承的。当我们调用setData(new Inetegr(5))时,will将调用setData(Integer)。如果我们编写Object o= new Integer(5); setData(o);,那么setData(Object)将调用。这不是真的。所以有两个问题:
发布于 2013-10-06 06:26:11
我是否正确理解引入桥接法的原因?
我想是的。如果编译器没有生成桥方法,那么子类中的方法将是超类方法的重载版本,而不是重写版本。你似乎已经明白了。
桥梁方法创造的必要条件和充分条件是什么?
当您扩展或实现参数化类型时,类型擦除将更改超类中方法的签名。
如果我们编写
Object o= new Integer(5); setData(o);,那么setData(Object)将调用。这不是真的。
我不明白你这么说是什么意思。您应该在非通用代码上测试这种行为。当方法重载时,方法调用将绑定到编译时,根据您传递的参数的声明类型确定哪种方法。因为在本例中声明的类型是Object,所以它将调用setData(Object)版本。
发布于 2013-10-06 06:39:31
这是一个应用桥技术的编译器,而不是我们。在您的示例中,编译器将在这里插入桥:
class MyNode extends Node<Integer> {
public void setData(Object data) {
setData((Integer) data);
}
...这就是使用它的原因:
Node<Integer> n = new MyNode();
n.setData(1);节点没有setData(整数),它有setData(对象)。MyNode桥方法setData(对象)重写它。JVM检测到实际的n类型是MyNode,并调用MyNode.setData(对象),这将重定向到setData(整数)。
应用桥方法的另一种情况是协变量返回类型:
class X implements Cloneable {
@Override
public X clone() {
...
}需要桥接器才能真正覆盖Object.clone。注意,在字节码方法中,签名包括返回类型。
https://stackoverflow.com/questions/19206012
复制相似问题