关于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);
}
}
随机推荐
- MVC 路由设置伪静态
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/ ...
- [COGS 2051] 王者之剑
Saber大法吼 2051. 王者之剑 ★★★☆ 输入文件:Excalibur.in 输出文件:Excalibur.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述 ...
- RabbitMQ入门-从HelloWorld开始
从读者的反馈谈RabbitMQ 昨天发完<RabbitMQ入门-初识RabbitMQ>,我陆陆续续收到一些反馈.鉴于部分读者希望结合实例来讲 期待下篇详细,最好结合案例.谢谢! 哪都好,唯 ...
- ASP.NET MVC 开发微信支付H5(外置浏览器支付)
H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付. 主要用于触屏版的手机浏览器请求微信支付的场景.可以方便的从外部浏览器 ...
- 44. leetcode 28. Implement strStr()
28. Implement strStr() Implement strStr(). Returns the index of the first occurrence of needle in ha ...
- Android Studio设置快捷键和背景
1.快捷键设置 复制代码并且向下移动 向下移动代码 代码提示 代码改错 更改文件名称 alt + shift + R 2.更改背景颜色-豆绿色 来自为知笔记(Wiz)
- CentOS6 安装Sendmail + Dovecot + Squirrelmail
本文记录在本地虚拟机CentOS6上搭建Sendmail + Dovecot + Squirrelmail 的Webmail环境的过程,仅仅是本地局域网的环境测试,不配置DNS, 也没有安全认证,Sq ...
- <Mastering KVM Virtualization>:第三章 搭建独立的KVM虚拟化
在第二章,你了解了KVM的内部结构:在本章中,您将了解如何将Linux服务器设置为虚拟化主机.我们正在讨论将KVM用于虚拟化并将libvirt作为虚拟化管理引擎. KVM开启了虚拟化并利用你的服务器或 ...
- Webservice 中涉及的几个概念
开发webservice有一段时间了.但是对其中的协议及实现一直存在疑惑.这里搜集相关概念.用以更好的理解它. 一.什么是Webservice WebService是一种跨编程语言和跨操作系统平台的远 ...
- 分辨率验证工具 - 【Firesizer】的使用升级-Firefox-29.0
今天打算使用Firesizer,但是在Firefox浏览器的右下角找不到Firesizer了. 在官网搜了搜(https://addons.mozilla.org/en-US/firefox/addo ...