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的泛型方法, ...
随机推荐
- hdu 1011 树形dp+背包
题意:有n个房间结构可看成一棵树,有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个房间有一定的敌人,每个士兵可以对抗20个敌人,士兵在某个房间对抗敌人使无法走开,同时有一个价值,问你花费这m个士 ...
- POJ 2186 Popular Cows 强连通分量模板
题意 强连通分量,找独立的块 强连通分量裸题 #include <cstdio> #include <cstdlib> #include <cstring> #in ...
- Install Linux Kernel 4.10 In CentOS and Ubuntu
https://www.ostechnix.com/install-linux-kernel-4-10-centos-ubuntu/
- SQL SERVER SQLOS的任务调度--微软亚太区数据库技术支持组 官方博客
https://blogs.msdn.microsoft.com/apgcdsd/2011/11/23/sql-server-sqlos/
- cocos2d-x HelloWorld 代码一撇
本节简单对新生成的hellowrold 项目相关代码进行简单分析,具体以代码注释的方式展示给大家.代码相对简单些,在此不作过多赘述,直接上码: int APIENTRY _tWinMain(H ...
- Appium+python自动化14-查看webview上元素(DevTools)
前言 app上webview的页面实际上是启用的chrome浏览器的内核加载的,如何把手机的网页加载到电脑上,电脑的chrome浏览器上有个开发模式DevTools,是可以方便调试的. 一.环境准备 ...
- nolock的使用
在SQL Server 2005数据库查询时,为了提高查询的性能,我们往往会在表后面加一个nolock,或者是with(nolock),让数据库在查询时不锁定表,从而提高查询的速度.本文我们就介绍SQ ...
- linux 程序移植到Android
用动态链接的方法: arm-linux-gcc hello.c -o hello.out -Wl,-dynamic-linker=/system/lib/ld-linux.so.3 并且拷贝文件到安卓 ...
- react组件引用时的default常见错误
1.下面使用方法是正确的: export class StepLoad extends React.Component {} 引用上面插件的方法,重命名 import {StepLoad as Ste ...
- POJ 1737 Connected Graph 题解(未完成)
Connected Graph Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3156 Accepted: 1533 D ...