看京东架构师是怎么从JVM底层来分析++i和i++

一、从JVM底层来分析++i或者是i++

开本堂公开课的原因是上周一个同学在群里面问了一个问题,群里面的同学都在讨论,各种解释各种答案,可谓是百家齐放,百家争鸣,但是没有一个可靠权威的答案,老师今天就趁七夕给大家带来权威的解释(从jvm字节码层面分析)。

DEMO:群926452303里争论的问题

public  class Hello{//public 修饰的类的名称要和文件名称保持一致(不考虑内部类的情况)
   public  static  void  main(String [] args){
          int  x=5;
		      x=++x  +  x++;
          System.out.println(x);//
   }
}

此时我们运行的结果是12,那为什么不是13呢?其实上代码分析到这里你发现了非常复杂难懂,自己都晕了,下面我们换一种更底层的思想来分析。

如果要彻底分析清楚这个问题,那么我们要从字节码指令层面来开始,如果要听懂本次课那么你先要掌握栈帧、操作数栈、局部变量的三个概念,现在就带着你来学习这几个概念。

1. 栈帧概念

在执行方法的时候jvm会在虚拟机栈中创建一个叫做栈帧的结构,这个栈帧由什么组成呢?分别由局部变量表、操作数栈、动态链接、返回地址、附加信息,那么与本次课有关是局部变量和操作数栈。

2.局部变量表

局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。

3.操作数栈(栈顶)

操作数栈也常被称为操作栈,它是一个后入先出栈,当一个方法刚刚执行的时候,这个方法的操作数栈是空的,在方法执行的过程中,会有各种字节码指向操作数栈中写入和提取值,也就是入栈与出栈操作。例如,在做算术运算的时候就是通过操作数栈来进行的,又或者调用其它方法的时候是通过操作数栈来行参数传递的。

package com.sun;
public class Test {
    public static void main(String[] args) {
        int  x=5;//局部变量,保存到一个叫做局部变量表的结构中
        x=++x  +  x++;
        System.out.println(x);
    }
}
/**
 Code:
 stack=2, locals=2, args_size=1
 0: iconst_5         //将一个int类型的常量5压入栈(栈顶)
 1: istore_1         //将栈顶的元素弹出保存到局部变量1号位置中 此时就是x==5
 2: iinc            1, 1  //表示局部变量表中1号位置的元素自增1 变成了x==6
 5: iload_1         //第一次把局部变量1号位置的元素压入栈顶,此时栈顶的第一个元素变的值变成了6
 6: iload_1         //第二次把局部变量1号位置的元素压入栈顶,此时栈顶的第二个元素变的值变成了6
 7: iinc            1, 1  //表示局部变量表中1号位置的元素自增1 变成了x==7(但是与栈顶的两个元素无关)
 10: iadd           //将栈顶的两个元素弹出进行相加(6+6),之后在压入栈变成了12
 11: istore_1        //将栈顶的元素弹出保存到局部变量1号位置中  此时局部变量1号位置变成12(x==12)
 12: getstatic     #2 //调用静态方法(与流有关)
 15: iload_1
 16: invokevirtual #3  //调用输出的方法在控制台输出  就是12
 19: return
 */

DEMO:继续分析代码

 //定义一个类
public  class Hello{//public 修饰的类的名称要和文件名称保持一致(不考虑内部类的情况)
   public  static  void  main(String [] args){
         int  x=5;//局部变量,保存到一个叫做局部变量表的结构中
		 x=++x  +  ++x;
		 System.out.println(x);//本次代码输出的值是多少?
   }
}

package com.sun;
public class Test {
    public static void main(String[] args) {
        int  x=5;//局部变量,保存到一个叫做局部变量表的结构中
        x=++x  +  ++x;
        System.out.println(x);
    }
}
/**
 Code:
 stack=2, locals=2, args_size=1
 0: iconst_5
 1: istore_1     x==5
 2: iinc          1, 1   x== 6
 5: iload_1        //栈顶元素值==6
 6: iinc          1, 1   //x==7
 9: iload_1       //栈顶的第二个元素就是7
 10: iadd         //栈顶的元素弹出相加再压入栈顶  变成13
 11: istore_1     //x==13
 12: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
 15: iload_1
 16: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
 19: return
 */

 

 

最后

IT行业的道路固然是充满了阳光了,一路上充满了美景,但是也充满了艰苦和崎岖,在突破了之后一路的阴霾,云霄之上,必然是一番广阔的云海。

  • 整理了一份关于java的系统化资料,从Javase- ssm-springcloud,包括了面试题,PDF电子书,网上商城项目,个人博客项目,分布式项目等都有想学习Java或者转行,大学生都非常实用,无任何套路免费提供,,加我裙下载,有什么问题都可以来问我----926452303点我即可进入
  • 最新Java精讲视频,PDF书籍教程,面试题,学习手册

在这里说一下,因为我是自学出来的,也深知自学的艰苦,如果你现在也在自学Java,在自学的过程当中有遇见任何关于学习方法,学习路线,学习效率等方面的问题,资料都可以评论留言,有遇见任

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值