Java面试:a+=a-=a*a原理解析

Java面试:a+=a-=a*a原理解析

a+=a-=a*a属于Java基础中比较难以理解的,面试中也经常会遇到这个问题,本篇博客对此问题进行分享总结。

1.问题代码

	public static void main(String[] args) {
		int a = 2;
		a+=a-=a*a;
		System.out.println("a="+a);
	}

我第一次遇见这个问题的时候,很不巧的算错了结果还和运行结果一致。在后面梳理思路时发现其中问题,反编译class文件才明白其中原理,感觉是个很有意思的问题。下面给出运行结果
运行结果
到这很多同学开始疑惑了吧,结果为什么不是-4。接下来看看JVM如何运行这段代码的。

 public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=2, args_size=1
         0: iconst_2
         1: istore_1
         2: iload_1
         3: iload_1
         4: iload_1
         5: iload_1
         6: imul
         7: isub
         8: dup
         9: istore_1
        10: iadd
        11: istore_1
        12: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        15: new           #3                  // class java/lang/StringBuilder
        18: dup
        19: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
        22: ldc           #5                  // String a=
        24: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        27: iload_1
        28: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        31: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        34: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        37: return
      LineNumberTable:
        line 5: 0
        line 6: 2
        line 7: 12
        line 8: 37
}

这是用javap -verbose反编译的代码。
先看指令号为2、3、4、5完成的事情,这四行指令完成了将运算需要的数据加载到操作数栈中。在这里插入图片描述
指令号6(imul)将栈顶两int型数值相乘并将结果压入栈顶
在这里插入图片描述
指令号7(isub)将栈顶两int型数值相减并将结果压入栈顶
在这里插入图片描述
指令号8(dup)复制栈顶数值并将复制值压入栈顶
在这里插入图片描述
指令号9(istore_1) 将栈顶int型数值存入局部变量表第二个位置,第一个赋值操作出现了。
在这里插入图片描述
关键点出现了,指令号10(iadd)将栈顶两个int值相加操作数栈现在只有-2和2,明显a+=a-=a*a中a+=的a并没有重新去栈中取值,准确的说四个a的值在计算开始时已经全部取出。所以最后相加的时候,用的是刚开始时定义的a的值。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值