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的泛型方法, ...
随机推荐
- 2015 UESTC 数据结构专题G题 秋实大哥去打工 单调栈
秋实大哥去打工 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 Descr ...
- intellj远程调试设置
场景:本地intelllij想远程调试服务器A,服务器A上起得是resin服务 步骤: 1.登陆服务器A,给resin添加启动参数. 方法一:修改resin.xml,修改完后重启resin服务器 在r ...
- Current limiter allows large USB bypass capacitance
The USB (Universal Serial Bus) specification requires a connected USB device to present a load to th ...
- 取maven copy部分
mvn deploy:deploy-file -DgroupId=com.mycompany -DartifactId=my-project -Dversion=1.0.0 -Dpackaging=j ...
- SQL SERVER 函数与SQL语法
http://www.cnblogs.com/hoojo/archive/2011/07/16/2108129.html
- linux下的系统调用函数到内核函数的追踪
http://blog.csdn.net/maochengtao/article/details/23598433
- C# 如何做类似微博和QQ的授权登录
记录下吧,dotnet下有这个http://dotnetopenauth.net/开源的框架可以用来实现服务端和客户端的实现,具体的使用方法还真研究,第一次接触OAuth这个概念
- ASP.NET Core 1.0基础之应用启动
来源https://docs.asp.net/en/latest/fundamentals/startup.html ASP.NET 5 使得应用对每个http请求有完整的控制权.Startup类是程 ...
- 简单的后台管理系统vue-cli3.0+element-ui
前段时间在研究一个分发系统,发现vue-cli+element-ui好像是挺不错的,然后自己根据那个分发系统尝试搭建了一下 1.首先安装vue和vue-cli // 全局安装vue npm insta ...
- 进程控制块(PCB)结构
一.进程控制块(PCB)结构 进程控制块(PCB)是系统为了管理进程设置的一个专门的数据结构.系统用它来记录进程的外部特征,描述进程的运动变化过程.同时,系统可以利用PCB来控制和管理进程,所以说,P ...