如何使用桥接方法实现协变 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
的原因
我目前正在学习 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 的原因