小编典典

如何使用Java中的桥接技术实现协变方法重写

java

在阅读协变量替代时,我发现一个非常奇怪的事实,

使用桥接技术实现协方差方法覆盖。它还说此功能是在java5及更高版本中实现的。(我认为这是因为从java5引入了泛型)

怎么发生的。请帮我举个例子。


阅读 216

收藏
2020-11-01

共1个答案

小编典典

考虑一个例子:

public interface Shape<T extends Shape<T>> {
    T getType();
    void setType(T type);
}

public class Circle implements Shape<Circle> {
    Circle getType() { }
    void setType(Circle circle) {  }
}

到目前为止看起来不错。但是,在擦除类型之后,接口松开了它的泛型类型,并将该类型T替换为上限。因此,接口和类如下所示:

public interface Shape {
    Shape getType();
    void setType(Shape type);
}

public class Circle implements Shape {
    Circle getType() { }
    void setType(Circle circle) {  }
}

现在,这就是问题所在。Circle擦除后的方法实际上不是的重写版本Shape。请注意,现在的方法看上去对所采用的参数和返回的值施加了更大的限制。这是因为擦除会更改接口中方法的签名。

为了解决此问题,编译器为此添加了桥方法,该方法将调用委派给类中的实际方法。

因此,该类实际上已转换为:

public class Circle implements Shape {
    Circle getType() { }
    void setType(Circle circle) {  }

    // Bridge method added by compiler.
    Shape getType() { return getType(); }  // delegate to actual method
    void setType(Shape shape) { setType((Circle)shape); }  // delegate to actual method
}

因此,bridge方法现在是接口中方法的重写版本,并且它们将调用委派给执行任务的实际方法。

注意,在这种情况下,桥接方法中使用的类型是接口类型参数的擦除Shape


参考文献:

2020-11-01