Java泛型 - 桥接方法? [英] Java Generics - Bridge method?

查看:22
本文介绍了Java泛型 - 桥接方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与 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 Objects 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 Objects...only one that takes two Integers.

下面的常见问题解答很好读.

The FAQ below is a good read.

这篇关于Java泛型 - 桥接方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆