zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    修改spring boot 启动logo
    查看jvm常用命令
    intellij IDEA破解
    hdu 新生晚会
    How many prime numbers(素数)
    2077 汉诺塔IV
    Factorial
    双人黑白块
    EasyX
    七夕情人节
  • 原文地址:https://www.cnblogs.com/daichangya/p/12960041.html
Copyright © 2011-2022 走看看