zoukankan      html  css  js  c++  java
  • java中i=i++字节码分析

    原文出处: Ticmy

    1
    2
    int i = 0;
    i = i++;

    结果还是0
    为什么?

    程序的执行顺序是这样的:因为++在后面,所以先使用i,“使用”的含义就是i++这个表达式的值是0,但是并没有做赋值操作,它在整个语句的最后才做赋值,也就是说在做了++操作后再赋值的,所以最终结果还是0

    让我们看的更清晰点:

    1
    2
    int i = 0;//这个没什么说的
    i = i++;//等效于下面的语句:
    1
    2
    3
    int temp = i;//这个temp就是i++这个表达式的值
    i++; //i自增
    i = temp;//最终,将表达式的值赋值给i

    这是java里的实现,当然在其他的语言如c或是c++中可能并不是这么处理的,每种语言都有各自的理由去做相应的处理。

    这警示我们:不要在单个的表达式中对相同的变量赋值超过一次

    让我们从字节码层次看一看,源码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Test {
     
        public static void main(String... args) {
     
            int i = 0;
     
            i = i++;
     
            System.out.println(i);
     
        }
    }

    使用javac编译后再使用javap -c Test反编译这个类查看它的字节码,如下(只摘取main方法):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static void main(java.lang.String[]);
     
    Code:
     
    0: iconst_0
     
    1: istore_1
     
    2: iload_1
     
    3: iinc 1, 1
     
    6: istore_1
     
    7: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
     
    10: iload_1
     
    11: invokevirtual #3; //Method java/io/PrintStream.println:(I)V
     
    14: return

    这里,我从第0行开始分析(分析中【】表示栈,栈的底端在左边,顶端在右边):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    0:将常数0压入栈,栈内容:【0
     
    1:将栈顶的元素弹出,也就是0,保存到局部变量区索引为为1(也就是变量i)的地方。栈内容:【】
     
    2:将局部变量区索引为1(也就是变量i)的值压入栈,栈内容:【0
     
    3:将局部变量区索引为1(也就是常量i)的值加一,此时局部变量区索引为1的值(也就是i的值)是1。栈内容:【0
     
    6:将栈顶元素弹出,保存到局部变量区索引为1(也就是i)的地方,此时i又变成了0。栈内容:【】
     
    7:获取常量池中索引为2所表示的类变量,也就是System.out。栈元素:【】
     
    10:将局部变量区索引为1的值(也就是i)压入栈。栈元素:【0
     
    11:调用常量池索引为3的方法,也就是System.out.println
     
    14:返回main方法
  • 相关阅读:
    python调包——hashlib加密
    初识-图论基础+拓扑排序的实现
    初识 基本数据结构和stl
    【寒假作业三】-带着作业的幌子打开影视剧的奇妙体验和学会挂作业的机
    scapy模块的学习
    【寒假作业三】——高级代码拼接工人的养成(改)
    寒假作业二-自救指南(网络基础)
    【寒假作业一】-编写踩雷指南
    寒假作业一-Github部分
    markdown基础(试水)
  • 原文地址:https://www.cnblogs.com/bojuetech/p/6005435.html
Copyright © 2011-2022 走看看