关于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);
}
}
随机推荐
- HDOJ-2006求奇数的乘积
Problem Description 给你n个整数,求他们中所有奇数的乘积. Input 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数 ...
- 【css】盒子模型 之 概述
摘要 一些基本的概念以及常见使用问题 概述 BFC 是css 中布局的核心 - 盒模型,根据块级元素及行级元素可分为块级容器, 行级容器,但容器内部都遵循 BFC BFC 空间布局 备注: IE 的盒 ...
- maven单元测试设置代理
背景 环境需要设置代理才能够访问外部网络,如果只是运行java程序来访问网络,我们可以通过java -jar test.jar -DproxyHost=proxy_ip -DproxyPort=pro ...
- poj 3253 Fence Repair 优先队列
poj 3253 Fence Repair 优先队列 Description Farmer John wants to repair a small length of the fence aroun ...
- XRD 数据处理:使用 Origin 进行多谱图对比
如果一个实验制备了 4 种不同条件下的样品,并分别测得了它们的 XRD 衍射谱图,那么在数据处理中如何用 Origin 软件得到一张多谱图对比的图呢? 样品间的谱图对比 如果只是谱图样品间对比(以 4 ...
- 推荐60个jQuery插件(转)
jQuery插件jQuery Spin Button自定义文本框数值自增或自减 jQuery插件JQuery Pager分页器实现javascript分页功能 jQuery插件FontSizer实现J ...
- 在webpack中使用Code Splitting--代码分割来实现vue中的懒加载
当Vue应用程序越来越大,使用Webpack的代码分割来懒加载组件,路由或者Vuex模块, 只有在需要时候才加载代码. 我们可以在Vue应用程序中在三个不同层级应用懒加载和代码分割: 组件,也称为异步 ...
- 分享一道JS前端闭包面试题
输出以下代码的结果 function fun(n,o){ console.log(o); return { fun:function(m){ return fun(m,n);//[1] } } } v ...
- 准备 macvlan 环境 - 每天5分钟玩转 Docker 容器技术(54)
除了 overlay,docker 还开发了另一个支持跨主机容器网络的 driver:macvlan. macvlan 本身是 linxu kernel 模块,其功能是允许在同一个物理网卡上配置多个 ...
- oracle 内连接,外连接
--内连接 inner join ... on --左外连接 left join ... on --右外连接 right join ... on 列: select * from stud ...