javac之BridgeMethod

When compiling a class or interface that extends a parameterized class or implements a parameterized interface, the compiler may need to create a synthetic method, called a bridge method, as part of the type erasure process. You normally don‘t need to worry about bridge methods, but you might be puzzled if one appears in a stack trace.

public class Node<T> {

    public T data;

    public Node(T data) { this.data = data; }

    public void setData(T data) {
        System.out.println("Node.setData");
        this.data = data;
    }
}
public class MyNode extends Node<Integer> {
    public MyNode(Integer data) { super(data); }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }
}

After type erasure, the Node and MyNode classes become:

public class Node {

    public Object data;

    public Node(Object data) { this.data = data; }

    public void setData(Object data) {
        System.out.println("Node.setData");
        this.data = data;
    }
}
public class MyNode extends Node {

    public MyNode(Integer data) { super(data); }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }
}

After type erasure, the method signatures do not match. The Node method becomes setData(Object) and the MyNode method becomes setData(Integer). Therefore, the MyNodesetData method does not override the Node setData method.

To solve this problem and preserve the polymorphism of generic types after type erasure, a Java compiler generates a bridge method to ensure that subtyping works as expected. For the MyNode class, the compiler generates the following bridge method for setData:

class MyNode extends Node {

    // Bridge method generated by the compiler
    //
    public void setData(Object data) {
        setData((Integer) data);
    }

    public void setData(Integer data) {
        System.out.println("MyNode.setData");
        super.setData(data);
    }

    // ...
}

As you can see, the bridge method, which has the same method signature as the Node class‘s setData method after type erasure, delegates to the original setData method.

时间: 2024-10-25 17:58:29

javac之BridgeMethod的相关文章

javac编译 编码GBK的不可映射字符

使用命令行javac命令编译java文件, 提示错误:编码GBK的不可映射字符. 在编译的时候,如果我们没有用-encoding参数指定我们的JAVA源程序的编码格式,则javac.exe会获得我们操作系统默认采用的编码格式. JDK根据操作系统的file.encoding参数(它保存的就是操作系统默认的编码格式,如WIN2k,它的值为GBK),把源程序从默认编码格式转化为JDK内部默认的UNICODE格式放入内存中.然后把转换后的unicode格式的文件进行编译成.class类文件,此时.cl

【javac】错误:编码GBK的不可映射字符

错误现象: 由于JDK是国际版的,我们在用javac.exe编译时,编译程序首先会获得我们操作系统默认采用的编码格式(也即在编译java程序时,若我们不指定源程序文件的编码格式,JDK首先获得操作系统的file.encoding参数(它保存的就是操作系统默认的编码格式,如WIN2k,它的值为GBK),然后JDK就把我们的java源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放入内存中.然后,javac.exe把转换后的UNICODE格式的文件进行编译成.cl

javac 编译命令的使用

工作中需要增量打包脚本,基本要求是从SVN服务器上download下java源码包,然后编译后,增量打包进application.jar.现在叙述一下我写脚本过程中不太熟悉的两个命令. 1. 从SVN服务器上下载源码包的命令:svn export --username  xiaopuser --password xiaoppass http://svnpath/project 2.在命令行下编译java文件的命令:javac  -Xlint   -classpath  lib/fr-xx-8.0

Java和Javac的使用时总提示找不到类模块的解决方案

1.场景: 争对网上的很多文章中javac编译与java运行的文章,有很多不明确的地方,使得在合适时发现很多坑.这里给大家作下简介. 2.Javac的使用注意: javac -d ./ ./InstallCert.java 其中-d表示要编译到哪里,加-d的目地是让后面加的java文件编译后,可以产生由package名称所确定的文件夹结构下的class文件.这样再运行java去执行时,就不会提示找不到类模块了. 3.Java的使用注意: java -classpath ./;c:\mylib.j

win10系统-javac不是内部或外部命令

给笔记本装了一个ssd,上午装的系统,重新搞jdk,设置JAVA_HOME之后,cmd运行Javac报 "javac不是内部或外部命令"各种懵逼,试了好几次才发现Path路径里面不能用%JAVA_HOME% 这类的相对路径,必须用绝对路径,必须用绝对路径,必须用绝对路径 重要的实行说三遍!!!

javac找不到或无法加载主类 com.sun.tools.javac.Main,

javac找不到或无法加载主类 com.sun.tools.javac.Main ecplise在配置jdk时,1(要选择jdk的那层目录D:\JDK\jdk_64\jdk,不要选择jre的那层),2(这个错误有有可能是环境变量的问题,还有可能是你的工程中确实没有tools这个包)我原因就是工程没有这个包,因为这个包是jdk自带的包,所以我就认为这个包不需要手动添加.最后测试,这个包是要手动添加到工程中的. 去掉不用的工作空间 1.去掉不用的工作空间Eclipse中,有些workspace不再使

java安装jdk时,执行javac出错

进来学习maven,在机器重新配置一套jdk, 卸载掉1.6,安装1.7是报javac不是有效的命令,java,java -version 都没问题.这个问题一直困扰了我好久,之间1.6也是这个问题,找解决方法,找了好久,今天装1.7依然如此,找的我快要疯了,以为是电脑系统的问题,准备明天重装系统了.在安装好maven ,输入mvn -version 是报jkd 的 JAVA_HOME安装有问题,很郁闷,结果一看,原来我一值是JAVA_HOME配置,配置的路径有点深入. 错误的JAVA_HOME

javac编译项目代码脚本片段

java -cp ".;.\ojdbc6.jar;WEB-INF\lib\commons-dbcp2-2.0.1.jar" TestJDBCjava -cp ".\classes;lib\*.jar" com.DH.M javac -classpath WEB-INF/classes -d WEB-INF/classes -sourcepath src/com/DH/PowerInfo.java javac -d WEB-INF/classes -sourcepat

用javac编译servlet类出现问题

本人写了一个关于servlet的webapp,但是在用javac编译的时候,只是单纯的将jsp-api.jar和servlet-api.jar拷贝放在了其目录下面,然后利用命令行 javac XXX.java开始编译,然后出现了一大堆错误,如下: FirstServlet.java:7: 错误: 找不到符号public class FirstServlet extends HttpServlet ^ 符号: 类 HttpServletFirstServlet.java:9: 错误: 找不到符号