java 泛型--桥方法
因为 java 在编译源码时, 会进行 类型擦除, 导致泛型类型被替换限定类型(无限定类型就使用 Object). 因此为保持继承和重载的多态特性, 编译器会生成 桥方法.
本文最后附录所有源码.
Pair 是个泛型类, 它具有泛型方法 setSecond(T second),
在经过编译时的 类型擦除 后变为 setSecond(Object second).
DateInterval 是 Pair<LocalDate> 的实例化子类, 它具有方法 setSecond(LocalDate second).
在 Main.main 中, 我们新建 DateInterval 对象, 并用基类 Pair<LocalDate> 来引用它,
此时调用基类的 setSecond 方法时, 我们希望它能够实现多态, 即调用 DateInterval.setSecond(LocalDate) 方法.
事实上, java 编译器通过插入 桥方法 的方式, 帮助我们实现了该功能.
反编译 DateInterval.class 会发现它具有两个 setSecond 方法:
void setSecond(LocalDate);void setSecond(Object).
并且, 在 void setSecond(Object) 中会调用 void setSecond(LocalDate), 这就是所谓的桥方法.
附: DateInterval.class 反编译后的代码:
Compiled from "DateInterval.java"
public class com.book.chapter8.DateInterval extends com.book.chapter8.Pair<java.time.LocalDate> {
public com.book.chapter8.DateInterval();
Code:
0: aload_0
1: invokespecial #1 // Method com/book/chapter8/Pair."<init>":()V
4: return
public void setSecond(java.time.LocalDate);
Code:
0: aload_1
1: aload_0
2: invokevirtual #2 // Method getFirst:()Ljava/lang/Object;
5: checkcast #3 // class java/time/chrono/ChronoLocalDate
8: invokevirtual #4 // Method java/time/LocalDate.compareTo:(Ljava/time/chrono/ChronoLocalDate;)I
11: iflt 19
14: aload_0
15: aload_1
16: invokespecial #5 // Method com/book/chapter8/Pair.setSecond:(Ljava/lang/Object;)V
19: return
public void setSecond(java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #6 // class java/time/LocalDate
5: invokevirtual #7 // Method setSecond:(Ljava/time/LocalDate;)V
8: return
}
附: 其他所有源码:
Pair.java:
package com.book.chapter8;
/**
* Created by zhixiao.mzx on 2016/11/5.
*/
public class Pair<T> {
private T first;
private T second;
public Pair() {
first = null;
second = null;
}
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;
}
}
DateInterval.java:
package com.book.chapter8;
import java.time.LocalDate;
/**
* Created by zhixiao.mzx on 2016/11/5.
*/
public class DateInterval extends Pair<LocalDate> {
public void setSecond(LocalDate second) {
if (second.compareTo(getFirst()) >= 0) {
super.setSecond(second);
}
}
}
Main.java:
package com.book.chapter8;
import java.time.LocalDate;
/**
* Created by zhixiao.mzx on 2016/11/5.
*/
public class Main {
public static void main(String[] args) {
DateInterval interval = new DateInterval();
Pair<LocalDate> pair = interval;
pair.setFirst(LocalDate.now());
pair.setSecond(LocalDate.now());
}
}
java 泛型--桥方法的更多相关文章
- JAVA泛型使用方法总结
1. 基本概念: (1)什么是泛型? 泛型,即"参数化类型".即将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用或 ...
- java泛型编译时被擦除引起多态的破坏,用 桥方法解决此类问题。(java 桥方法)
在JVM虚拟机中泛型编译的时候,会出现类型擦除.但是,在多态场景中,编译时,擦除方式会出现多态被破坏的可能. 举个栗子: A.java public class A<T> { void g ...
- java 泛型的类型擦除与桥方法
泛型类 --代码参考:java核心技术 卷1 第十版 public class Pair<T> { private T first; private T second; //构造器 pub ...
- java 泛型的类型擦除和桥方法
oracle原文地址:https://docs.oracle.com/javase/tutorial/java/generics/erasure.html 在Java中,泛型的引入是为了在编译时提供强 ...
- 0072 Java中的泛型--泛型是什么--泛型类--泛型方法--擦除--桥方法
什么是泛型,有什么用? 先运行下面的代码: public class Test { public static void main(String[] args) { Comparable c=new ...
- Java中的类型擦除与桥方法
类型擦除 Java在语法中虽然存在泛型的概念,但是在虚拟机中却没有泛型的概念,虚拟机中所有的类型都是普通类.无论何时定义一个泛型类型,编译后类型会被都被自动转换成一个相应的原始类型. 比如这个类 pu ...
- 使用java泛型设计通用方法
泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...
- 初识Java泛型以及桥接方法
泛型的由来 在编写程序时,可能会有这样的需求:容器类,比如java中常见的list等.为了使容器可以保存多种类型的数据,需要编写多种容器类,每一个容器类中规定好了可以操作的数据类型.此时可能会有Int ...
- java泛型应用实例 - 自定义泛型类,方法
近 短时间需要使用泛型,就研究了下,发现网上的问关于泛型的文章都是讲原理的, 很少有提到那里用泛型比较合适, 本文就泛型类和泛型方法的使用给出两 个典型应用场景. 例如一个toString的泛型方法, ...
随机推荐
- Java解释执行和编译执行
以前有句话说:“Java是解释执行的 ” .现在看来确实不是很准确,至于原因,在此简略解释: 首先,我们先解释一下在Java中解释执行和编译执行的区别. 解释执行:将编译好的字节码一行一行地翻译为机器 ...
- bzoj1502 simpson求面积
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题解: simpson积分求面积,s = (f(a)+f(b)+4*f(c))/6*Δx ...
- [转][Android] ListView中getView的原理+如何在ListView中放置多个item
ListView 和 Adapter 的基础 工作原理: ListView 针对List中每个item,要求 adapter “给我一个视图” (getView). 一个新的视图被返回并显示 如果 ...
- 利用DC/DC开关调节器延长DSP系统的电池寿命 - 动态电压调节
http://www.analog.com/zh/content/dc-to-dc_switching_regulator_insights/fca.html 作者:Sridhar Gurram,Ol ...
- Spring注入日期到bean属性-CustomDateEditor
这一个Spring例子向您展示如何为bean属性注入一个“日期”. package com.yiibai.common; import java.util.Date; public class Cus ...
- 关于orcad元件库
ORCAD CAPTURE 零件库解析 ORCAD CAPTURE 零件库解析 1' AMPLIFIER.OLB 共182个零件,存放模拟放大器IC,如CA3280,TL027C,EL4093等. 2 ...
- win10怎么彻底关闭自动更新
原文:https://jingyan.baidu.com/article/9faa7231e7b78b473c28cbb6.html 方法/步骤 1 单击左下角开始菜单点击设置图标进入设置界面 2 ...
- scp遇到路径中有空格
sudo scp root@1.1.1.1:/test/soft/123/Microsoft SQL Server 2000.iso . 错误! sudo scp root@1.1.1.1: ...
- Mac OSX 系统目录结构(转)
摘要 在OS X的系统中,不再有Windows用户熟悉的C盘.D盘,这是因为OS X底层是Unix系统,其目录机构符合Unix系统的规范.MAC机器主板使用了Intel主导的EFI标准,硬盘分区格式采 ...
- thinkphp输出表格
//这是打印5列n行的表格,所以mod="5" value="4" <tr> <volist name="data" id ...