如何使用桥接方法实现协变 return 类型

How covarient return type is implemented using bridge method

我目前正在学习 java 仿制药 "java generics and collection by Maurice Naftalin 2006"。

在 return 类型的协变覆盖部分中,作者声明

有人可以向我解释一下,实现是什么,即桥接方法中的代码是什么样的?桥接方法是否调用原始方法(即具有签名public Point clone()的方法)?

我建议你参考Oracle material关于它并进行一些测试以了解桥接机制。

Bridge 是超越 Java 1.5 之前编译时不变的覆盖方法能力的神器。

Java 1.5 supports covariant return types. What does this mean? Before 1.5, when you override a superclass method, the name, argument types and return type of the overrding method has to be exactly same as that of superclass method. Overriding method is said to be invariant with respect to argument types and return type.

If you change any argument type, then you are not really overriding a method -- you are actually overloading it.

桥就是桥:所以它构成了link。这里它介于具有原始 return 类型的方法和具有协变 return 类型的覆盖方法之间。
所以是的,你是对的。

你想检查一下吗? 编译class然后反汇编它的源代码。

$ javap -c Point.class

你会得到类似的东西:

Compiled from "Point.java"
public class Point {
  public Point(int, int);
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: aload_0
       5: iload_1
       6: putfield      #2                  // Field x:I
       9: aload_0
      10: iload_2
      11: putfield      #3                  // Field y:I
      14: return

  protected Point clone() throws java.lang.CloneNotSupportedException;
    Code:
       0: new           #4                  // class Point
       3: dup
       4: aload_0
       5: getfield      #2                  // Field x:I
       8: aload_0
       9: getfield      #3                  // Field y:I
      12: invokespecial #5                  // Method "":(II)V
      15: areturn

  protected java.lang.Object clone() throws java.lang.CloneNotSupportedException;
    Code:
       0: aload_0
       1: invokevirtual #6                  // Method clone:()LPoint;
       4: areturn
}

可以看到Object clone()Point clone()之间的委托。
当然你不能写这样的代码,因为 return 在编译时 Java 中不允许基于类型的重载,但在运行时 JVM 可以使用已编译的 classes 中的此功能。

Could someone please explain to me, what does the implementation, i.e. the code inside the bridge method would look like?

这里我们举个例子:class java.text.AttributeEntry contains a bridge method getKey().

  • 这里是这个方法的call graph

  • 这里是这个方法的decoded byte code

并且here列出了JDK中的所有bridge方法。回顾其中的几个,我们可能会得出以下结论:

  • bridge只是简单地调用原始方法
  • 所以这就是名字 bridge
  • 的原因