• 深入理解java虚拟机-第十章-早期(编译期)优化


    第10章  早期(编译期)优化

    javac编译过程:

      1、解析与填充符号表过程

      词法、语法分析 将源代码的字条流转变为标记(Token)集合。如“int a = b + 2”这名代码包含了6个标记,分别是int a = b + 2

      填充符号表

      2、注解处理器

      3、语义分析与字节码生成

      标注检查 包括诸如变量使用前是否已被声明、变量与赋值之 间的数据类型是否能够匹配,还有一个重要的动作称为常量折叠

      数据及控制流分析  对程序上下文逻辑更进一步的验证,它可以检查出诸如程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确处理了第问题。

      解语法糖  泛型、变长参数、自动装箱/拆箱等

        java中的泛型只在程序源码中存在,在编译后的字节码中就已经替换为原来的原生类型了,并且在相应的地方插入强制类型转换代码。

      字节码生成

      Java方法中的泛型

      Java的泛型在编译后就擦除了,所以如下代码会编译出错:

      

      因为参数List<Integer>和List<String>编译之后都被搾除了,变成了一样的原生类型 List,导致这两种方法的牲签名变得一模一样。修改代码如下:

      

      便可以编译,方法的重载成功。Class文件方法表(method_info)的数据结构时,方法重载要求方法具备不同的特征签名,返回值并不包含在方法的特征签名之中,所以返回值不参与重载选择,但在Class文件格式中,只要描述符不是完全一致的两个方法就可以共存。也就是说,两个方法如果有相同的名称和特征签名,那它们也是可以合法地共存于一个Class文件中的。执行结果如下:

      

      说明Java还是能够正常执行重载的泛型的方法,Java编译进已经把泛型擦除了,为什么还能进行重载的方法呢?

      

      如图 28 35行为调用Java的编译后代码,

        28行为第一次调用JavaTest.test(ss),参数为List<Integer>的时候。

        35行为第二次调用JavaTest.test(ssa),参数为List<String>的时候。

      说明虽然编译会擦除泛型,但也会为泛型的调用方法进行相应的编译。

      

  • 相关阅读:
    总结几个面试题
    产生下一个排列数的算法
    所谓码农
    简记微软实习生面试
    二维数组作为函数的参数传递
    详细解说 STL 排序(Sort)
    copy()之绝版应用
    STL标准模板库(简介)
    访问控制和继承方式
    常用软件开发模型比较分析
  • 原文地址:https://www.cnblogs.com/zyzl/p/4188461.html
Copyright © 2020-2023  润新知