再次分析i++与i--

原创 2012年03月22日 22:15:36

之前一篇 i++与i--的分析  ,说明了在执行i++或i--操作时,应运用所学的计算机知识:数据操作的原理,应理解清楚操作数和栈的关系。当时也没整理清楚。最近又遇到i++和i--相关的题。又把自己给整懵了。在看了解析class反编译文件  后,也去分析class文件,最终算是真正弄明白了i++和i--。

在要理解i++和i--的原理之前,需要明白java的栈和堆方面的知识。这里就不再介绍栈和堆了。下面主要贴图说明i++的实现原理。只要分析清楚了i++,i--就不在话下。

下面看java源程序:

 

package com.michael.test;

/**
 * @author michael
 * @email wqjsir@foxmail.com
 * @version 1.0
 */
public class TestMain {

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


在dos下先编译该文件javac TestMain.java

再执行javap -verbose TestMain输出如下

Compiled from "TestMain.java"
public class com.michael.test.TestMain extends java.lang.Object
  SourceFile: "TestMain.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method       #5.#14; //  java/lang/Object."<init>":()V
const #2 = Field        #15.#16;        //  java/lang/System.err:Ljava/io/PrintStre
const #3 = Method       #17.#18;        //  java/io/PrintStream.println:(I)V
const #4 = class        #19;    //  com/michael/test/TestMain
const #5 = class        #20;    //  java/lang/Object
const #6 = Asciz        <init>;
const #7 = Asciz        ()V;
const #8 = Asciz        Code;
const #9 = Asciz        LineNumberTable;
const #10 = Asciz       main;
const #11 = Asciz       ([Ljava/lang/String;)V;
const #12 = Asciz       SourceFile;
const #13 = Asciz       TestMain.java;
const #14 = NameAndType #6:#7;//  "<init>":()V
const #15 = class       #21;    //  java/lang/System
const #16 = NameAndType #22:#23;//  err:Ljava/io/PrintStream;
const #17 = class       #24;    //  java/io/PrintStream
const #18 = NameAndType #25:#26;//  println:(I)V
const #19 = Asciz       com/michael/test/TestMain;
const #20 = Asciz       java/lang/Object;
const #21 = Asciz       java/lang/System;
const #22 = Asciz       err;
const #23 = Asciz       Ljava/io/PrintStream;;
const #24 = Asciz       java/io/PrintStream;
const #25 = Asciz       println;
const #26 = Asciz       (I)V;

{
public com.michael.test.TestMain();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return
  LineNumberTable:
   line 8: 0


public static void main(java.lang.String[]);
  Code:
   Stack=2, Locals=2, Args_size=1
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iinc    1, 1
   6:   iinc    1, 1
   9:   iload_1
   10:  iadd
   11:  istore_1
   12:  getstatic       #2; //Field java/lang/System.err:Ljava/io/PrintStream;
   15:  iload_1
   16:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V
   19:  return
  LineNumberTable:
   line 11: 0
   line 12: 2
   line 13: 12
   line 14: 19


}

这里主要分析对数据操作部分。其他部分可参考前一篇 解析class反编译文件

下面贴图说明数据的操作过程:

 

 经过上面的分析,可以知道在对数据执行基本运算时都是对操作数栈中的数据进行操作。而对保存在堆中的变量本身没有影响。

看下面的代码:

代码一:

public class TestMain {

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


 代码二:

public class TestMain {

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

代码一二的输出结果都为2。通过上面的分析就能理解为什么等于2了。

 

 

JAVA i++ i-- 与 ++i --i的区别

/** JAVA运算符之i++ i-- ++i --i的运算 **/ class Demo5{ public static void main(String[] args){ int i ...
  • ckinghan58
  • ckinghan58
  • 2017年02月12日 22:28
  • 320

Java--关于 i++ 与 ++i

在《Java程序员面试宝典》里面有提到i++这个部分:   j++,是一个依赖于java里面的“中间缓存变量机制”来实现的,   通俗的说:   ++在前就是“先加后赋”(++j)   ...
  • zlQQhs
  • zlQQhs
  • 2012年12月13日 00:52
  • 3304

关于 i++ 和 ++i i-- 和 --i 的那些事儿

++、--运算符既可以放在变量之前(如++i、--i),也可放在变量之后(如i++、i--)。两者的差别是放在变量之前,先增加1(或减少1),再取值;放在变量之后,先取值,再增加1(或减少1)。如对于...
  • u014746965
  • u014746965
  • 2015年04月11日 13:43
  • 945

i++与i--的分析

以前总认为i++和i--是个很简单的运算,每次做题遇到这类的题总是跳过。知道最近,一初学java的朋友,问我i++和i--的含义。而我却被他写的表达式给懵住了。 表达式如下:  int i = 0 ;...
  • wqjsir
  • wqjsir
  • 2010年01月20日 00:07
  • 709

关于printf("%d,%d",i--,i++)的问题

首先看几种情况 1、 int i=1; printf("%d,%d\n",i--,i++);运行结果为:2,1 这与编译器有关,通过汇编可以很清楚的看到 第一步:把i的值存入缓存器[ebp-...
  • u014644714
  • u014644714
  • 2017年08月29日 22:20
  • 1096

i++ 与 ++i 的执行过程

经常遇到 i++ 或者 ++i 什么的
  • triumph92
  • triumph92
  • 2014年11月19日 16:27
  • 437

i++与 i--执行效率

文章出处:http://www.limodev.cn/blog 作者联系方式:李先静 昨天同事问了我一个问题,有两个循环语句: for(i = n; i > 0; i–) { … } ...
  • linux_embedded
  • linux_embedded
  • 2012年12月27日 20:17
  • 491

i++和++i的区别以及在for循环中效果一样解惑

 ++i是先执行 i=i+1在使用i的值 而i++是先使用i的值再执行i=i+1。 for中其实不管是i++或++i都是在for循环体全部执行完毕后才执行, 如: for(int...
  • Harder_and_Luckier
  • Harder_and_Luckier
  • 2015年08月17日 15:18
  • 589

Java多线程之i++的安全性问题

问题: 两个线程同时对i=0的数据分别进行i++一百次,结果出来并不是200。理论上来讲,结果最小值为2,最大值为200。 首先解释一下为什么会这样。 i++并非原子操作。执行过程中JVM从内存...
  • zrh_lawliet
  • zrh_lawliet
  • 2016年12月09日 21:22
  • 1998

Java i=i++;i = ?

int i=0;       i=i++;       结果i是多少?       这是一个经常被提及的问题,答案一直五花八门。       具体测试一下以说明问题:       代码1: p...
  • lingzhm
  • lingzhm
  • 2015年03月19日 16:03
  • 1311
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:再次分析i++与i--
举报原因:
原因补充:

(最多只允许输入30个字)