硫辨姥 发表于 2026-1-18 17:20:00

Java泛型---桥方法

桥方法

桥方法是为了解决类型擦除后与多态的冲突。为了理解什么是桥方法。下面举实例,假设有一个泛型类Pair,它用来保存两个值,first与second,first永远比second大。
现在,创建一个子类去继承它。
package Test;import java.time.LocalDate;public class Pair{   private T first;   private T second;   public Pair(){};   public Pair(T first, T second) {       this.first = first;       this.second = second;   }   public T getFirst() {       return first;   }   public void setFirst(T first) {       this.first = first;   }   public T getSecond() {       return second;   }   public void setSecond(T second) {       this.second = second;   } }class DateInterval extends Pair {   public void setSecond(LocalDate second){       if(second.compareTo(getFirst()) >=0)         super.setSecond(second);   }}那么呢,这个子类重写了父类的setSecond,这是我们的意图,要去重写这个方法,那么注意看子类的方法。由于它继承的是Pair类,所以这个方法的参数也要是LocalData,毕竟要时这个日期保持在第二。现在回到泛型类Pair,它的方法类型擦除后是什么样子
public void setSecond(Object second){   this.second = second; }很明显,两个方法的参数不一样,并没有达到重写的目的,而是变成了重载。问题就在这里,如果我们编写下面的代码
       DateInterval dateInterval = new DateInterval(); //创建一个实例      Pair pair = dateInterval; //父类引用子类实例      pair.setSecond(LocalDate.now());上面的代码是典型的多态概念的体现,根据对象的实际类型而非声明类型来决定调用哪个方法的过程,所以此时,预期中肯定是调用实例的方法。但此时,多态特性与类型擦除产生了冲突,编译器会生成一个桥方法。如果没有桥方法,那它会调用本身的方法,也就是原始类型的setsecond(Objects second)方法。为了解决这个问题,编译器在DateInterval类中生成一个桥方法
public void setSecond(Object second){setSecond((LocalData) Second);}强制调用预期的方法。这就是桥方法,通过搭建一座看不见的桥,使程序符合Java特性。然而,这样看不见的特性,怎么去证明它确实存在?其一是,这样的桥方法是编译器自动生成,如果你手动编写这样的方法,会与编译器生成的产生冲突,从而报错。
https://img2024.cnblogs.com/blog/3677043/202601/3677043-20260118160909389-350231573.png
其二是通过JDK自带查看字节码的工具,对编译后的.class文件执行以下命令。
bash javap -c -v DataInterval.class
https://img2024.cnblogs.com/blog/3677043/202601/3677043-20260118161408800-796477029.png
欲重写父类的方法字节码
https://img2024.cnblogs.com/blog/3677043/202601/3677043-20260118161510856-1738379840.png
编译器自动生成的setSecond方法,可以很明显的看到它方法的参数是Object。至于其余的代码,我们主要看这一行:
java 5: invokevirtual #25               // Method setSecond:(Ljava/time/LocalDate;)V
类似的,重写父类的get方法
class DateInterval extends Pair{    //编译器自动生成桥方法    public LocalDate getSecond(){      //返回父类的second值并转为LocalDate类      return (LocalDate) super.getSecond();    }    }编译器会生成下面的桥方法
LocalDate getSecond(); Object getSecond();//父类继承总之,对Java泛型的转换,记住以下几点:

[*]虚拟机中没有泛型,只有普通的类和方法。
[*]所有类型参数都会替换为他们的限定类型。
[*]会合成桥方法来保持多态
[*]为保持类型安全性,必要时会强制插入类型转换。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

二艰糖 发表于 2026-2-3 03:54:39

鼓励转贴优秀软件安全工具和文档!

纪睐讦 发表于 2026-2-5 06:05:12

懂技术并乐意极积无私分享的人越来越少。珍惜

客臂渐 发表于 2026-2-6 01:30:46

懂技术并乐意极积无私分享的人越来越少。珍惜

石娅凉 发表于 2026-2-9 14:02:11

不错,里面软件多更新就更好了

左丘雅秀 发表于 2026-2-9 18:32:51

收藏一下   不知道什么时候能用到

盒礁泅 发表于 2026-2-9 22:17:33

谢谢楼主提供!

接快背 发表于 2026-2-10 06:27:17

喜欢鼓捣这些软件,现在用得少,谢谢分享!

旁拮猾 发表于 2026-2-10 17:32:45

谢谢分享,辛苦了

佴莘莘 发表于 2026-2-11 04:11:10

前排留名,哈哈哈

电棘缣 发表于 2026-2-13 08:13:25

热心回复!

艺轫 发表于 2026-2-18 06:11:20

懂技术并乐意极积无私分享的人越来越少。珍惜

缑娅瑛 发表于 2026-2-20 04:26:01

喜欢鼓捣这些软件,现在用得少,谢谢分享!

毋献仪 发表于 2026-3-6 01:47:12

谢谢楼主提供!

捐催制 发表于 2026-3-8 06:39:08

热心回复!

后沛若 发表于 2026-3-10 08:53:53

前排留名,哈哈哈

盛天欣 发表于 2026-3-11 08:28:25

谢谢分享,辛苦了

勉欤铅 发表于 4 天前

用心讨论,共获提升!

热琢 发表于 昨天 07:31

鼓励转贴优秀软件安全工具和文档!

喳谍 发表于 2 小时前

过来提前占个楼
页: [1]
查看完整版本: Java泛型---桥方法