• JDK编译器针对final变量的优化


    使用的是oracle jdk7具体版本是: (build 1.7.0_01-b08)

    1.方法作用于的final变量:

    源码:

    public void methodScopeFinal(){
    final int age = 22;
    final String firstName = "xu";
    int nextAge = age+1;
    String name = firstName+"guoping";

    javap -c反编译得到的jvm指令, 可以看出jvm指令中没有包含对两个final变量(方法作用于中的final成为变量是合适的,因为很多时候需要根据不同的传入参数赋予不同的值)的定义,只有对age+1和firstName+"guoping"的最后结果赋值。

      public void methodScopeFinal();
        Code:
           0: bipush        23
           2: istore_3
           3: ldc           #2                  // String xuguoping
           5: astore        4
           7: return

     ------------------------------------------------------------------------------------------------------------------------------------------------

     作为对比看下去掉final变量后的指令:

     public void methodScopeFinal(){

    int age = 22;
    String firstName = "xu";
    int nextAge = age+1;
    String name = firstName+"guoping";
    }

     没有使用final后的指令要多出很多,包括对age和firstName两个变量的定义和赋值以及后面的加法指令和字符串连接运算指令。

      public void methodScopeFinal();
        Code:
           0: bipush        22
           2: istore_1
           3: ldc           #2                  // String xu
           5: astore_2
           6: iload_1
           7: iconst_1
           8: iadd
           9: istore_3
          10: new           #3                  // class java/lang/StringBuilder
          13: dup
          14: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
          17: aload_2
          18: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          21: ldc           #6                  // String guoping
          23: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          26: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          29: astore        4
          31: return

    =====================================================================================

    final变量定义类: 

    public class FinalClassVariableTest

    {
    public final int age = 22;
    public final int anotherAge = getAnotherAge();
    public final String firstName = "xu";
    public int getAnotherAge(){
    return 5;
    }

     final变量使用类:FinalClassVariableTest 

     public void testClassFinal(){

    FinalClassVariable fcVariable = new FinalClassVariable();
    int age = fcVariable.age;
    int anotherAge = fcVariable.anotherAge;
    String name = fcVariable.firstName;
    }

    FinalClassVariableTest 上述
    方法的指令可以看出对FinalClassVariable 对象中final int和string在指令中不是通过变量去引用而是直接保存对应的常量值:22和"xu",

    因此应该注意:如果修改了primitive和string类型的final变量值,不仅要编译单个类最好要把整个工程都全部编译。否则会导致引用到final变量的地方还是修改以前的常量值。 

    public static final情形编译器做相同的处理。 

    上面method对应的jvm指令: 

      public void testClassFinal();
        Code:
           0: new           #2                  // class FinalClassVariable
           3: dup
           4: invokespecial #3                  // Method FinalClassVariable."<init>":()V
           7: astore_1
           8: aload_1
           9: invokevirtual #4                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
          12: pop
          13: bipush        22
          15: istore_2
          16: aload_1
          17: getfield      #5                  // Field FinalClassVariable.anotherAge:I
          20: istore_3
          21: aload_1
          22: invokevirtual #4                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
          25: pop
          26: ldc           #6                  // String xu
          28: astore        4
          30: return


  • 相关阅读:
    实战DeviceIoControl 之五:列举已安装的存储设备
    zend server 安装及相关配置
    php中echo 与print 的区别
    PHP:Deprecated: Function set_magic_quotes_runtime() is deprecated 错误
    php与ascii码
    计算EXCEL列名代号的程序
    笔记本电脑键盘不能正常输入字符
    读写注册表
    创建用于监视对student表进行插入和更新操作的触发器
    在客户机上安装Windows服务
  • 原文地址:https://www.cnblogs.com/xinglongbing/p/2228422.html
Copyright © 2020-2023  润新知