a=a++引发的思考

前言

最近越来越感觉到java基础的重要性,开始重新拾起封存已久的《Thinking in java》,偶然的一个小案例引发了此次的思考。

Demo

首先一个小的demo:

public class Test {
    public static void main(String[] args) {
        int a = 1;
        System.out.println("1:"+ a);
        a++;
        System.out.println("2:"+ a);
        ++a;
        System.out.println("3:"+ a);
        a = ++a;
        System.out.println("4:"+ a);
        a = a++;
        System.out.println("5:"+ a);
        a = a++ + ++a;
        System.out.println("6:"+ a);
        int b = a++;
        System.out.println("7:"+ a);
        System.out.println("8:"+ b);
    }
}

java入门时都会遇到过的小案例,前三个答案相信都会随口而出,但是第四个才是此次探索的问题所在,上面答案如下:
1:1
2:2
3:3
4:4
5:4
6:10
7:11
8:10
回答正确的可以绕过本篇文章,回答错误的跟笔者一起探索下去吧。

代码分析

  1. a++ 和 ++a 区别不在过多赘述,a++是先执行表达式后++,++a是先++再执行表达式。
  2. a = ++a; 从上的结果可以得出a=3,此时a先++等于4,再赋值给a。此时a=4无异议。
  3. a = a++; 从上的结果可以得出a=4,此时a先被赋值为4,再执行++,此时a=5。为什么++未生效呢?这篇文章主要就是这个问题的探讨,具体原因可以参考下面对jVM的分析。
  4. a = a++ + a++; 从上的结果可以得出a=4,运算时第一个a仍为4,然后经过a++为5,又因为++a先执行++,此时a=6,所以结果4+6=10。
  5. b = a++; 从上的结果可以得出a=10,此时b先被a赋值为10,a再执行++为11。对比上面的第三点,此时++也生效,什么原因?见JVM分析。

JVM分析

上述Demo可以通过java自带的javap查看字节码文件,命令如下:
javac Test.java
javap -c Test.class
觉得分不清的可以分别对语句进行查看字节码文件,以下是笔者的探索过程。

  1. a++和++a的字节码分析(两个字节码基本相同):

    0: iconst_1                    1压入栈顶
    1: istore_1                    栈顶值(1)存入局部变量1(a)
    2: iinc          1, 1          变量1自加(a++或++a操作,自加后变量1的值为2)  
    
  2. a=++a的字节码分析:

    0: iconst_3                    3压入栈顶
    1: istore_1                    栈顶值(3)存入局部变量1(a)
    2: iinc          1, 1          变量1自加(++a操作,自加后变量1的值为4)
    5: iload_1                     变量1的值压入栈顶(值为4)
    6: istore_1                    将栈顶值(4)存入变量1(=操作)
    
  3. a=a++的字节码分析:

    0: iconst_4                    4压入栈顶
    1: istore_1                    栈顶值(4)存入局部变量1(a)
    2: iload_1                     变量1的值压入栈顶(值为4)
    3: iinc          1, 1          变量1自加(a++操作,自加后变量1的值为5)
    6: istore_1                    将栈顶值(4)存入变量1(=操作)  
    
  4. b=a++的字节码分析:

    0: bipush        10            10压入栈顶
    2: istore_1                    栈顶值(10)存入局部变量1(a)
    3: iload_1                     变量1的值压入栈顶(值为10)
    4: iinc          1, 1          变量1自加(a++操作,自加后变量1的值为11)
    7: istore_2                    栈顶值(10)存入局部变量2(b)(=操作)
    

从3可以看出a=a++,a++操作后并没有压入栈,返回a的值为栈顶值4,所以a从5又被赋值为4。对于1,2本质上只是对变量操作,并没有计算的赋值逻辑,对于4,变量b被赋值栈顶值为10,变量a自加后为11。以上为思考全过程,如果不足请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值