关于i++和++i
初学Java,经常看到i++和++i的一些问题,在此整理一下。
首先看下面一个小程序:
- public class atest{
- public static void main(String args[]){
- int s=1,m=1,n=1,p=1;
- s++;
- ++m;
- n=n++;
- p=++p;
- System.out.println("s="+s+"; m="+m+"; n="+n+"; p="+p);
- }
- }
输出为s=2; m=2; n=1; p=2
这里比较难以理解的应该是n的值,下面我们对程序进行反编译进行分析:
E:\test>javap -c atest
Compiled from "atest.java"
public class atest {
public atest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":
()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: istore_1
2: iconst_1
3: istore_2
4: iconst_1
5: istore_3
6: iconst_1
7: istore 4
9: iinc 1, 1
12: iinc 2, 1
15: iload_3
16: iinc 3, 1
19: istore_3
20: iinc 4, 1
23: iload 4
25: istore 4
27: getstatic #2 // Field java/lang/System.out:Ljava/
io/PrintStream;
30: new #3 // class java/lang/StringBuilder
33: dup
34: invokespecial #4 // Method java/lang/StringBuilder."<
init>":()V
37: ldc #5 // String s=
39: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
42: iload_1
43: invokevirtual #7 // Method java/lang/StringBuilder.ap
pend:(I)Ljava/lang/StringBuilder;
46: ldc #8 // String ; m=
48: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
51: iload_2
52: invokevirtual #7 // Method java/lang/StringBuilder.ap
pend:(I)Ljava/lang/StringBuilder;
55: ldc #9 // String ; n=
57: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
60: iload_3
61: invokevirtual #7 // Method java/lang/StringBuilder.ap
pend:(I)Ljava/lang/StringBuilder;
64: ldc #10 // String ; p=
66: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
69: iload 4
71: invokevirtual #7 // Method java/lang/StringBuilder.ap
pend:(I)Ljava/lang/StringBuilder;
74: invokevirtual #11 // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
77: invokevirtual #12 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
80: return
}
对相关部分进行分析,注释如下:
0: iconst_1 //把1放到栈顶
1: istore_1 //把栈顶的值放到局部变量1中,即s
2: iconst_1 //把1放到栈顶
3: istore_2 //把栈顶的值放到局部变量2中,即m
4: iconst_1 //把1放到栈顶
5: istore_3 //把栈顶的值放到局部变量3中,即n
6: iconst_1 //把1放到栈顶
7: istore 4 //把栈顶的值放到局部变量4中,即p
9: iinc 1, 1 //把局部变量1(也就是s),增加1,这个指令不会导致栈的变化,s此时变成2
12: iinc 2, 1 //把局部变量2(也就是m),增加1,这个指令不会导致栈的变化,m此时变成2
15: iload_3 //把局部变量3(也就是n)的值放到栈顶,此时栈顶为1
16: iinc 3, 1 //把局部变量3(也就是n),增加1
19: istore_3 //把栈顶的值放到局部变量3(也就是n)中
20: iinc 4, 1 //把局部变量4(也就是p),增加1
23: iload 4 //把局部变量4(也就是p)的值放到栈顶,此时栈顶为2
25: istore 4 //把栈顶的值放到局部变量4(也就是p)中
由此看见,i=i++是先将i的值放到栈顶,而后对i进行操作,最后返回给i的栈顶值还是先前的值,而i=++i是先对i进行操作,然后将i的值放到栈顶,最后返回给i的栈顶值也就是计算后的值。
扩展练习:
- public class atest{
- public static void main(String args[]){
- int s=0,m=0,n=0,p=0;
- for(int i=0;i<100;i++){
- s++;
- ++m;
- n=n++;
- p=++p;
- }
- System.out.println("s="+s+"; m="+m+"; n="+n+"; p="+p);
- }
- }
随机推荐
- Jmeter实现MD5加密
Jmeter3.0以后的版本不再内置MD5加密函数,只能自己写了. 1.编码 package com.liuke.test; import java.security.MessageDigest; i ...
- ES6解构赋值
前面的话 我们经常定义许多对象和数组,然后有组织地从中提取相关的信息片段.在ES6中添加了可以简化这种任务的新特性:解构.解构是一种打破数据结构,将其拆分为更小部分的过程.本文将详细介绍ES6解构赋值 ...
- 【ES6】变量的解构赋值
1. 数组 var [a, b, c] = [1, 2, 3]; let [a, [b], d] = [1, [2, 3], 4]; 默认值生效的条件是,对象的属性值严格等于undefined. [x ...
- Java复习随笔
1.StringTokenizer str = new StringTokenizer("字符串"); str.countTokns(); //可得出字符串非连续的个数(可用于 ...
- 如何自己写一个公用的NPM包
以markdown-clear,创建过程为例,讲解整个NPM包创建和发布流程 1 如何创建一个包 1.1 创建并使用一个工程 在GitHub上新建一个仓库,其名markdown-clear clone ...
- hdu--3782--找规律--xxx定律
/* Name: hdu--3782--xxx定律 Date: 17/04/17 21:34 Description: 找规律题,又想打表了 */ /* for(int i=2;i<30;++i ...
- MySQL xtrabackup之--databases 勿手贱
xtrabackup备份单库时,必须指定--databases,但是如果将databases写成了database,那么xtrabackup备份的就是整个数据库,以下是 uuid = 397ae42e ...
- 1.怎样控制div中的图片居中
答案如下: #div{ width: 100%; height: 100%; border: 1px solid #000; text-align: center;}#div img{ vertica ...
- ES6 浅谈let与const 块级作用域之封闭空间(闭包)
ES6新增了 let const 命令,用来声明变量.它的用法类似于 var ,但是所声明的变量,只在 let const 命令所在的代码块内有效. var const 不允许重复声明 用处: 可 ...
- HTML indexedDB数据库—简单示例
indexedDB数据库的基本概念:在HTML5中,新增一种被称为"indexedDB"的数据库,该数据库是一种存储在客户端本地的NoSQL数据库. <!DOCTYPE ht ...