• 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


  • 相关阅读:
    (转)C#特性详解
    PHP MSSQL数据操作PDO API
    DWR
    配置JAVA的环境变量
    关​于​h​i​b​e​r​n​a​t​e​中​双​向​外​键​关​联​o​n​e​-​t​o​-​o​n​e​的​p​r​o​p​e​r​t​y​-​r​e​f​=​的​问​题(转)
    Hibernate 二级缓存 总结整理(转)
    EhCache 分布式缓存/缓存集群(转)
    MySQL分区表(转)
    通用权限设计
    (转)关于Struts 2 拦截器参数丢失问题
  • 原文地址:https://www.cnblogs.com/xinglongbing/p/2228422.html
Copyright © 2020-2023  润新知