Java i++ 与 ++i 学习

文章目录

  • 前言
  • 一、i++与++i的底层
  • 二、拓展延伸
  • 二、变异
  • 总结


前言

对于Java中i++与++i在日常使用中也是经常出现,但是之前本人认知仅止步于前者先使用后增加,后者先增加后使用,最近得空研究了一下他们的字节码文件,恍然大悟!记录一下这个小成长!


一、i++与++i的底层

	@Test
    public void testInc(){
        int i =1;
        i = i++;
        //1
        System.out.println(i);
    }

    @Test
    public void testInc1(){
        int i =1;
        i = ++i;
        //2
        System.out.println(i);
    }

两者的结果很明显能看出来,但是在JVM编译之后执行的过程中发生了什么呢?
首先通过IDEA的 jclasslib ByteCode Viewer 插件查看两者的字节码文件(插件怎么安装请自行百度!)
Java i++ 与 ++i 学习_第1张图片
Java i++ 与 ++i 学习_第2张图片
想必各位和我刚开始看的时候一样,一脸懵逼(大佬无敌!)
接下来请看详细解释,如有错误欢迎各位大佬指正!
Java i++ 与 ++i 学习_第3张图片
Java i++ 与 ++i 学习_第4张图片
注意:连接线上对应的为左侧字节码的序号,指向的为该布操作的结果!
想必到这里大家都应该了解i++与++i在执行的时候到底为什么不一样了吧?
原因就是两者相加的操作和进栈的操作顺序不同

二、拓展延伸

基本的知道了那就看两个比较复杂的!

	@Test
    public void testInc2(){
        int i =1;
        i += ++i + i++;
        //5
        System.out.println(i);
    }

    @Test
    public void testInc3(){
        int i =1;
        i += i++ + ++i;
        //5
        System.out.println(i);
    }

Java i++ 与 ++i 学习_第5张图片
Java i++ 与 ++i 学习_第6张图片
这两个方法虽然输出都是5,但是他们的底层是怎样的呢?
换句话说就是5=?+?
来吧,上图,解密!
Java i++ 与 ++i 学习_第7张图片
从这儿就能看出来***i += ++i + i++*** 相当于 1+2+2
Java i++ 与 ++i 学习_第8张图片
而***i += i++ + ++i*** 则是 1+1+3
这就是因为两者操作局部变量和操作栈的顺序不一样导致的;

二、变异

既然i++和++i 已经差不多了,那就看个特殊的!

    @Test
    public void testInc5(){
        int a =0;
        for (int i = 0; i < 9 ;i++){
            a = a++;
        }
        System.out.println(a);
    }

    @Test
    public void testInc6(){
        int a =0;
        for (int i = 0; i < 9 ;i++){
            a++;
        }
        System.out.println(a);
    }

这两个方法的输出又各是多少呢?
看上去差不多,但是结果却不一样,上面的结果是0,下面的结果是9,原因是什么呢?
大家都能看出来是 = 原因,但是为什么一个等号会引发这样的差异呢?
来看字节码!
Java i++ 与 ++i 学习_第9张图片
这就不画内存图了,简单的看下,应该都注意到了关键点:a=a++ 相比较于 a++ 多了一步 istore_1的字节码操作,这一步操作是什么意思呢?
Java i++ 与 ++i 学习_第10张图片
红色框中的意思是:将栈顶元素弹出,并赋值给变量;
也就是 a = a ++;在执行时,局部变量虽然进行了+1操作,但是栈里面还是0,进行出栈操作的值是0,并且出栈的0替换了局部变量的1,成功将a再次改为了0;
而a++; 则没有出栈操作,一直都是局部变量在增加,在最后输出时都是 局部变量 进栈,然后打印输出;
所以造成的结果就是前者在输出前进栈的是0,后者进栈的是9。

总结

所以i++ 与 ++i归根结底只是两者局部变量操作是否进栈,以及等号出栈或者最后输出时局部常量进栈影响

以上就是最近研究的关于i++与++i的所得,记录一下,同时也算是分享,如有错误,欢迎指正!。

你可能感兴趣的:(#,基础学习,java,jdk,jvm)