`

用java字节码解释i++和++i

    博客分类:
  • java
阅读更多

先看4个题目:

①int i = 0;

    i = i++;

 

②int i = 0;

    i = ++i;

 

③int i = 0;

    int j = 0;

    j = i++ + i++;

 

④ int i = 0;

     int j = 0;

     j = i++ + i++ + i++;

每道题里的i和j都是多少?

用myeclipse测试,结果分别是①i = 0,②i = 1,③i = 2,j = 1,④i = 3,j = 3。

i++和++i的问题,困扰很多人。网上、书上的解释各种各样。现在通过分析字节码,来确定这两条语句究竟是怎样执行的。

 

先给出今天要用到的字节码的含义

 

Bytecode

Stack

before->after

Description

iconst_0

->0

Loads the int value 0 onto the stack

istore_1

value->

Store int value into variable 1

istore_2

value->

Store int value into variable 2

iinc

No change

Increment local variable #index by signed byte const

iload_1

->value

Loads an int value from variable 1

iadd

value 1,value 2->result

Adds 2 ints together

 

 

 

 

 

 

 

 

 

 

说明两点需要注意的地方:

①iinc操作是有参数的,但是在此忽略,简写为iinc,此操作对应于自加操作,并且该操作不对stack有任何改变;

②iadd操作过后只在stack中保留结果result。

 

接下来是四段程序主要的字节码:

①iconst_0        ②iconst_0        ③iconst_0       ④iconst_0

    istore_1            istore_1            istore_1           istore_1

    iload_1             iinc 1,1              iconst_0          iconst_0

    iinc 1,1             iload_1              istore_2           istore_2

    istore_1            istore_1            iload_1             iload_1

                                                      iinc 1,1             iinc 1,1

                                                      iload_1             iload_1

                                                      iinc 1,1             iinc 1,1

                                                      iadd                  iadd

                                                      istore_2            iload_1

                                                                               iinc 1,1

                                                                               iadd

                                                                               istore_2

 

现在解释①。第一步在stack中存入一个int常量0;第二步把它赋值给第一个变 量,即我们的i;第三步把第一个变量i的值存入到stack中;第四步在i自身的空间进行自加,而第三步存入到stack中的值没有变;第五步把第三步存 入到stack中的值再赋值给第一个变量i。也就是说,i真的是进行自加了,但是被自己原来的值覆盖掉了。从这里我们可以看出,自加操作比赋值操作的优先 级高。

 

再看②。和①比较起来,区别就在于,++i是先进行自加,然后把自加后的值存入到stack中,所以最后赋值给i的是1,不是0。

 

③呢?首先,③比前两个多了一个变量,但这不是重点。往下看,把第一个变量i的值 (0)存入到stack中,i自加,再第一个变量i的值(1)存入到stack中,再自加。此时stack中有两个值了,0和1,进行加操作后的结果是 1,然后赋值给第二个变量j。这里颠覆了我们以前被告知的,加的运算优先级比自加高。这就是困扰我们的,其实,只要把值读入到stack中,接下来就进行 自加,只有得到了两个参数,才进行加操作。

 

来看④。前面都和③一样,只到进行了第一次加操作,得到的结果(1)保存在stack中,没有赋值给j,然后再次读入i的值(2)到stack,i自加,得到加操作的两个参数,1和2,进行第二次加操作的结果是3,赋值给j。

 

到此,问题都解决了。

 

转自:http://blog.csdn.net/tutuhatec/article/details/6747774

分享到:
评论

相关推荐

    Java 字节码概述

    Java 编译器不将对变量和方法的引用编译为数值引用,也不确定程序执行过程中的内存布局,而是将这些符号引用信息保留在字节码中,由解释器在运行过程中创立内存布局,然后再通过查表来确定一个方法所在的地址。...

    Java字节码(.class文件)格式详解((转载)

    Java字节码是Java程序在运行时被JVM(Java虚拟机)解释执行的一种中间语言。每个Java类都由一个`.class`文件表示,其中包含了编译后的字节码指令。`.class`文件的结构非常严谨,它不仅包含了类的信息,如类名、方法...

    JAVA字节码操作库 BCEL

    **JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java开发的一个重要工具,主要用于处理Java字节码。它为开发者提供了一种深入理解与操作Java类文件的底层机制,允许分析、创建、修改和优化字节...

    Java字节码揭秘

    - **定义**:Java虚拟机是一种运行Java字节码的虚拟机,能够独立于操作系统和硬件平台运行。 - **JVM规范**:提供了JVM的标准行为描述,包括内存模型、类格式、字节码指令集等。 - **JVM具体实现**:不同的供应商...

    i = i++ 代码分析

    在 Java 中,源代码首先被编译成字节码,然后被解释执行。在反编译过程中,我们可以使用 javap 命令来反编译字节码,从而获得源代码。 在 Java 中,反编译是一个非常重要的技术,它可以帮助我们了解 Java 程序的...

    ASM操作字节码,动态生成Java类class文件

    ASM是一个开源的Java字节码操控和分析框架,它能够用来动态生成类或者增强已有类的功能。ASM可以被用来创建Java代理、实现元编程、甚至...在学习和使用ASM时,理解Java字节码规范以及如何映射到ASM的API是非常重要的。

    现代 Java 字节码编辑器.zip

    下载启动器使用方法和说明可在启动器仓库中找到快照版本请参阅发布工件的CI 操作独立发行 (目前 4X 没有)特征轻松地从高级或低级编辑 Java 字节码(减去烦人的部分)Recaf 中的编辑器功能抽象出了已编译 Java 应用...

    4.程显峰--Java字节码技术1

    Java字节码技术是Java平台的核心组成部分,它与Java虚拟机(JVM)紧密相连,为各种编程语言在Java平台上提供了可移植性和高效执行的基础。本篇将详细讲解Java字节码的概念、用途以及JVM如何执行字节码。 首先,让...

    jvm-java字节码规则.pdf

    Java虚拟机(JVM)是运行Java程序的核心引擎,负责解释、执行Java字节码。Java字节码是一种中间语言,可以在任何安装了JVM的机器上运行,使得Java程序具有跨平台的能力。Java源代码在编译成.class文件时,会被编译器...

    Java字节码指令集的使用详细

    本文将深入探讨Java字节码指令集的使用和特性。 首先,字节码指令由一个字节的操作码定义其功能,如果需要参数,这些参数随后跟随。操作数的长度和数量根据不同的指令而变化。对于多字节的操作数,JVM采用大端序...

    java习题 字节码文件

    - **类加载机制:** Java虚拟机在运行时动态地加载字节码文件,并对其进行验证和解释执行。 **字节码文件阅读与理解:** 根据题目描述,要求阅读并理解`Greetings.java`,然后编写一个具有相同功能但能在浏览器中...

    cpp-ToyJVM用C编写的实验性Java字节解释器

    本文将深入探讨一个特别的项目——"cpp-ToyJVM",这是一个用C语言编写的实验性Java字节码解释器,它为学习者提供了从底层角度理解Java运行机制的宝贵机会。 Java字节码是Java虚拟机(JVM)执行的二进制代码,它独立...

    C2j-Compiler:将C语言转换为Java字节码或可以直接解释执行的编译器(将C语言编译成Java字节码的编译器,也可以选择直接解释执行)

    将C语言转换为Java字节码或可以直接解释执行的编译器 作为一个学习项目 可以解释为执行大多数C或编译为Java字节码 玩具级,未添加许多功能,也没有优化 支持的 支持所有基本陈述 解释器:支持指针,数组,结构和...

    详解java面试题中的i++和++i

    Java中i++和++i的详解 Java中的i++和++i是两个常见的运算符,经常出现在面试题中。它们的作用都是将变量i加1,但是它们的执行顺序和返回值却有所不同。 首先,让我们从字节码的角度来看addAfterReturn和...

    专题资料(2021-2022年收藏)关于java中i=i的解释.doc

    在 Java 中,`i++` 和 `++i` 两者的主要区别在于操作顺序:`i++` 是先使用当前值,然后增加;而 `++i` 是先增加,再使用新值。这个问题在 Java 中特别重要,因为它的行为可能会让人感到意外。 首先,让我们回顾一下...

    java字节码指令集.docx

    Java字节码指令集的设计使得JVM可以高效地解释和执行代码,同时提供了跨平台兼容性。理解这些指令对于优化代码、调试问题以及深入学习JVM的工作原理至关重要。通过这些指令,开发者可以更好地理解和控制程序在JVM...

    HelloWorld的javap -verbose HelloWorld 字节码初探

    在描述中提到的链接是一个博客文章,可能详细解释了如何使用`javap -verbose`选项来解析和解释字节码。`-verbose`选项提供了更详细的输出,包括类加载、主方法、以及每个方法的字节码和局部变量表等信息。 标签...

Global site tag (gtag.js) - Google Analytics