Java泛型 - 桥接方法? [英] Java Generics - Bridge method?
问题描述
与 Java 泛型相关的一种叫做桥接方法"的概念让我停下来思考它.
Something called the "bridge method" concept related to Java Generics made me stop at a point and think over it.
顺便说一句,我只知道它发生在字节码级别,不可用供我们使用.
Btw, I only know that it occurs at the bytecode level and is not available for us to use.
但我很想知道 Java 编译器使用的桥接方法"背后的概念.
But I am eager to know the concept behind the "bridge method" used by the Java compiler.
幕后到底发生了什么以及为什么使用它?
What exactly happens behind the scenes and why it is used?
对示例的任何帮助将不胜感激.
Any help with an example would be greatly appreciated.
推荐答案
该方法允许扩展泛型类或实现泛型接口(带有具体类型参数)的类仍用作原始类型.
It's a method that allows a class extending a generic class or implementing a generic interface (with a concrete type parameter) to still be used as a raw type.
想象一下:
public class MyComparator implements Comparator<Integer> {
public int compare(Integer a, Integer b) {
//
}
}
这不能以其原始形式使用,传递两个 Object
进行比较,因为类型被编译到比较方法中(与如果它是泛型类型参数会发生的情况相反)T,类型将被擦除).因此,在幕后,编译器添加了一个桥接方法",它看起来像这样(如果它是 Java 源代码):
This can't be used in its raw form, passing two Object
s to compare, because the types are compiled in to the compare method (contrary to what would happen were it a generic type parameter T, where the type would be erased). So instead, behind the scenes, the compiler adds a "bridge method", which looks something like this (were it Java source):
public class MyComparator implements Comparator<Integer> {
public int compare(Integer a, Integer b) {
//
}
//THIS is a "bridge method"
public int compare(Object a, Object b) {
return compare((Integer)a, (Integer)b);
}
}
编译器保护对桥接方法的访问,强制直接对其进行显式调用会导致编译时错误.现在该类也可以以其原始形式使用:
The compiler protects access to the bridge method, enforcing that explicit calls directly to it result in a compile time error. Now the class can be used in its raw form as well:
Object a = 5;
Object b = 6;
Comparator rawComp = new MyComparator();
int comp = rawComp.compare(a, b);
为什么还需要它?
除了添加对显式使用原始类型的支持(主要是为了向后兼容)之外,还需要桥接方法来支持类型擦除.使用类型擦除,这样的方法:
Why else is it needed?
In addition to adding support for explicit use of raw types (which is mainly for backwards compatability) bridge methods are also required to support type erasure. With type erasure, a method like this:
public <T> T max(List<T> list, Comparator<T> comp) {
T biggestSoFar = list.get(0);
for ( T t : list ) {
if (comp.compare(t, biggestSoFar) > 0) {
biggestSoFar = t;
}
}
return biggestSoFar;
}
实际上编译成与此兼容的字节码:
is actually compiled into bytecode compatible with this:
public Object max(List list, Comparator comp) {
Object biggestSoFar = list.get(0);
for ( Object t : list ) {
if (comp.compare(t, biggestSoFar) > 0) { //IMPORTANT
biggestSoFar = t;
}
}
return biggestSoFar;
}
如果桥接方法不存在,并且你传递了一个 List
和一个 MyComparator
到这个函数,在标记为 IMPORTANT 的行的调用
会失败,因为 MyComparator
将没有名为 compare
的方法,它需要两个 Object
...只有一个需要两个 整数
s.
If the bridge method didn't exist and you passed a List<Integer>
and a MyComparator
to this function, the call at the line tagged IMPORTANT
would fail since MyComparator
would have no method called compare
that takes two Object
s...only one that takes two Integer
s.
下面的常见问题解答很好读.
The FAQ below is a good read.
这篇关于Java泛型 - 桥接方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!