zoukankan      html  css  js  c++  java
  • 8.1.11编译时常量解析

    8.1.11编译时常量解析

    在第7章讲过,被初始化为编译时常量的静态final变量的引用,在编译时被解析为常量值的 一个本地拷贝,这对于所有的基本类型和java.lang.String都是正确的。

    这种对于常量的特别处理使Java语言具有了两个特性。首先,常量值的本地拷贝使得静态 final变量可以用于switch语句中的case表达式。在字节码中实现switch语句的两条虚拟机指令是 tableswitch和lookupswitch,需要case值内嵌在字节码流中。这些指令不支持运行时解析case值。 要了解这两条指令的更多信息,请参阅第16章。

    隐藏在常量的特殊处理后面的另一个动机是条件编译。通过if语句(其表达式解析成编译时常量),java支持条件编译。下面是一个例子:

    // On CD-ROM in file linking/ex2/AntHill.java
    class AntHill {

    static final boolean debug = true;
    }


    // On CD-ROM in file linking/ex2/Example2.java
    class Example2 {

    public static void main(String[] args) {
    if (AntHill.debug) {
    System.out.println("Debug is true!");
    }
    }
    }

    因为基本类型常量的特别处理,Java编译器可以通过AntHill.debug的值,决定是否包括 Example2.main ()中的if语句体。因为在这个情形下AntHill.debug是true, javac为Example2的main()方法生成的字节码中就包含if语句的语句体,但是并不包括检查AntHill.debug的值。在 Example2的常量池中并没有指向类AntHill的符号引用。下面是main ()方法的字节码:

    如果指向AntHill.debug的引用是在运行时解析的,编译器就需要检查AntHill.debug的值和if语句的语句体,以防AntHill.debug的值改变了。实际上AntHill.debug的值编译之后就不可能改变, 因为它声明为final。然而,仍然可以改变AntHill的源代码并重新编译AntHill,但是不重新编译 Examp1e2。

    因为指向AntHill.debug的引用是在编译时解析的,编译器如果发现AntHill.debug是false,编译器就会有条件地编译if语句的语句体。请注意,这意味着如果只是把AntHill设置为false,只重新编译AntHill,而无法改变Example2程序的行为。必须也重新编译Example2。

    下面的Example3,是把Example2的名字换成了Example3,并且把AntHill的debug值设置为 false时的编译结果。

    下面是javac生成的Example3的main ()方法的字节码。

    0 return // return void

    可以看到,Java编译器把整个if语句都从Example3.main()方法中去处了。在这个短短的 字节码序列中,甚至没有任何println ()调用的提示。

  • 相关阅读:
    汇编14:端口
    汇编13:int指令
    整个软件开发的流程
    css grid 布局
    socket粘包处理
    如何做好需求变更管理?——需求变更流程规范
    软件工程需求分析文档模板
    使用layui的form.on绑定select选中事件, form.on()不执行的原因分析
    ID4收藏
    ASP.NET MVC5中View-Controller间数据的传递
  • 原文地址:https://www.cnblogs.com/mongotea/p/11979618.html
Copyright © 2011-2022 走看看