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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值