无聊代码,深沉的理解

看到一段三行的代码,引起了一次小小的探索。记录这次的记忆,方便以后的回归。

代码如下:

public static void main(String[] args) {
        int i = 8;
        i = i++;
        System.out.println(i);
}

这个i输出几呢?
我们先一步步的分析,int i = 8;这没啥好说的,就是一个赋值。
那么i = i++呢?我们都知道i++ 的意思就是我先用一下你的值,再给你的值加个1,那在i++了以后,在给它赋值给i呢。到这里,你是不是会以为:i=i++ 不就是 8+1 ,再把这个整体赋值给i了,最后输出就是9呀。这也太简单了吧。真是如此吗?我们接着往下看:
检验程序最好的方法就是运行程序看结果,运行结果如下:
运行图片
嗯哼?这为什么是8呢?不是说好的是9吗?
不着急的,慢慢往下看。
为了解开这个为什么,我打开了一个idea的插件叫:jclasslib.
这个插件打开了以后界面如下:
jclasslib
接着打开他的【方法】的文件夹。
方法
对于解出为什么是8,不重要的内容,就不详细的解释了,这里主要说一下的是两个,一个是main下面的code,还有一个是LocalVariableTable,这两个,我们先说一下,LocalVariableTable,是个什么东西,这个简单的来说就是一个表格,这个表格存放着这个方法所使用到的全部的局部变量,那么可想而知这个LocalVariableTable,里面对于上面写的这段程序中,一定有一个局部变量i,还有一个就是args,点开看一下:
局部变量
看表名字的字段,一个是args,一个是i。要注意的是序号,我们现在的i所在的序号是1,这个很重要,后面有用。在i的上面有行:cp_info #17 这一行的意思就是这个i这个名称,存放在了常量池中的第17这个位置上,有兴趣的可以自己去了解,这里就不多BB了。当然上面的两个局部变量表中,肯定要找到他们
重点来了,当我们点一下main文件夹下面的code的时候,就出现了这么一堆东西:
指令
上图中字节码下面的这一堆东西,就是这段程序在JVM中全部运行的指令。也就是说,我们只要理解了这些指令在干嘛的,也就理解了为什么会输出8的疑问的,怀着激动的心情,一条条的看。
首先第一条:

bipush 8.的大致意思就是要把8放入到一个栈中。好的,一个栈中存了一个8.


istore_1 这条指令在官方的文档中写的是 istore_
这个指令大致的意思就是,将上面的的那个栈中的值,出栈,出栈的值去哪里呢?就是_1也就是去局部变量表中为1的那个变量上,我们从上面可以看到这个为1的值就是i呀。


我们总结下这两个指令,先是将一个8压栈,然后又将这个8出栈,并且将这个8给了局部变量表中的i,也就是我们上面方法中的,int i =
8;在这两个指令中,完成了。我们接下去继续看。


iload_1 这条指令的大致意思就是:我要把局部变量表中的位置为1上面的值取出来,然后压到栈中。那么我们上面在局部变量表中为1的位置上是i,并且值为8.那么这句话执行完了以后,栈中又有了一个值,还是那个8.


接着一条指令是:

iinc 1 by 1:
这条指令的大致意思就是:给我找到局部变量表中,位置为1的那个值,给我加上一个1。那这条指令执行完成了以后,我们会得到两个数:一个是局部变量表中的值是8+1=9,并且栈中还有一个8.


下面一条指令又是 istore_1 为什么是istore_1呢?我们上面的代码是i =
i++,我们的i++已经在上面完成了,在哪里完成的,在局部变量表中完成的。那么istore_1我们上面讲过,这个指令的意思就是将栈的数据出栈,然后将出栈的这个值,给局部变量表中位置为一的那个变量。执行了这个指令,也就是把我们栈中的8,又给了局部变量表中的i.那么现在局部变量中的i就是8了。

看到这里,是否已经明白了呢?原来8是这么来的。
如果有想了解jvm指令的,可以自己去oracle的官方文档中看,最权威的书,莫过于官方文档。
oracle JVM指令

那如果上面的程序改成

public static void main(String[] args) {
        int i = 8;
        i = ++i;
        System.out.println(i);
}

又会有哪些有趣的指令呢?自己去瞅瞅吧。

玄学的程序,艺术的编程。
如果问题请多多指教。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值