Java中的自增问题(i=i++)
也许我这是在较真, 但是我们确实有时候就不小心就错写为这种情况了。
看如下代码:
public class Test{ public static void main(String[] args){ int a = 3; int b = 5; a = a++; b = ++b; } }
这时候, 如果输出 a 和 b ,那么 他们的值是什么? 答案是 a = 3; b = 6;
如果你感到迷惑, 那么继续往下看, 如果你知道其中的原理,那么就不用看了。
我们利用 jdk 自带的两个命令(javac,javap)来看看 JVM 虚拟机到底在底层做了些什么。
建立一个文件 Test.java 并把上面的代码写入其中, 然后里用 javac 命令编译
wuqinglong@debian:~$ javac -g:vars Test.java
然后利用 javap 命令查看 JVM 编译之后的虚拟机指令。
wuqinglong@debian:~$ javap -verbose Test
输出如下内容
Classfile /home/wuqinglong/Test.class Last modified 2016-3-16; size 326 bytes MD5 checksum 2e2f3ec62c26d0e1e53bb121e83b9032 public class Test minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #3.#17 // java/lang/Object."<init>":()V #2 = Class #18 // Test #3 = Class #19 // java/lang/Object #4 = Utf8 <init> #5 = Utf8 ()V #6 = Utf8 Code #7 = Utf8 LocalVariableTable #8 = Utf8 this #9 = Utf8 LTest; #10 = Utf8 main #11 = Utf8 ([Ljava/lang/String;)V #12 = Utf8 args #13 = Utf8 [Ljava/lang/String; #14 = Utf8 a #15 = Utf8 I #16 = Utf8 b #17 = NameAndType #4:#5 // "<init>":()V #18 = Utf8 Test #19 = Utf8 java/lang/Object { public Test(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LTest; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=3, args_size=1 0: iconst_3 // 将int类型的3送到栈顶 1: istore_1 // 将栈顶的int类型的值存储到slot为1的int类型的本地变量中,slot编号对应的变量名在后三行。 2: iconst_5 // 将int类型的5送到栈顶 3: istore_2 // 将栈顶的int类型的值存储到slot为2的int类型的本地变量中 4: iload_1 // 将slot为1的int类型的本地变量加载到栈顶 5: iinc 1, 1 // 将slot为1的本地int类型的变量的值加1 8: istore_1 // 将栈顶的int类型的值存储到slot为1的本地变量中 9: iinc 2, 1 // 将slot为2的本地intbeijing的变量的值加1 12: iload_2 // 将slot为2的int类型的本地变量加载到栈顶 13: istore_2 // 将栈顶的int类型的值存储到slot为2的int类型的本地变量中 14: return // 结束 LocalVariableTable: // 变量对应的slot编号如下 Start Length Slot Name Signature 0 15 0 args [Ljava/lang/String; 2 13 1 a I 4 11 2 b I }
如果有点汇编知识的话,看上面的代码会比较好理解点, 如果没有学过汇编指令的话, 就看注释。
其中最主要的区别是:
对于 a = a++; JVM 进行的操作是:
1. 将本地变量的值加载到栈顶 (注意: 这时候这个值是没有经过自增操作的)
2. 对本地变量的值进行自增(对栈顶对象没有影响)
3. 把栈顶变量的值存储到本地变量中(重新对本地变量赋值,栈顶变量的值并没有进行自增操作,自增操作是对本地变量进行操作的)
对于 b = ++b; JVM 进行的操作是:
1. 将本地变量的值先自增
2. 将自增完之后的本地变量的值加载到栈顶(注意:这时候这个值是经过了自增操作的)
3. 将栈顶变量的值存储到本地变量中
Java中的自增问题(i=i++)的更多相关文章
- 【Java】【4】关于Java中的自增自减
摘要:理解j = j++与j = ++j的区别:正确用法:直接用j++,不要用前两种 正文: import java.util.*; public class Test{ public static ...
- java中的自增问题
运行下面这段代码,其结果是什么呢? package com.test; public class Inc { public static void main(String[] args) { Inc ...
- java中集合的增删改操作及遍历总结
集合的增删改操作及遍历总结
- java中双向链表的增、删、查操作
import java.util.NoSuchElementException; public class DoublyLinkedListImpl<E> { private Node h ...
- Java中的自增自减
情况①: for (int i = 0; i < 100; i++) { j = 1 + j++; } System.out.println(j); 结果是 0 !! 这是由于在进行后自增/自减 ...
- Java中AtomicInteger的使用!!!
今天在看Volley的源码的时候,看到里面使用了AtomicInteger这个类,曾经没用过,今天看了一下API学习了一下: 首先介绍一下这个类的用处,这个类主要是用来替换java中的自增和自减操作, ...
- Android(java)学习笔记186:对ListView等列表组件中数据进行增、删、改操作
1.ListView介绍 解决大量的相似的数据显示问题 采用了MVC模式: M: model (数据模型) V: view (显示的视图) C: controller 控制器 入门案例: acit ...
- Android(java)学习笔记129:对ListView等列表组件中数据进行增、删、改操作
1. ListView介绍 解决大量的相似的数据显示问题 采用了MVC模式: M: model (数据模型) V: view (显示的视图) C: controller 控制器 入门案例: aci ...
- java中如何理解:其他类型 + string 与 自增类型转换和赋值类型转换
java中如何理解:其他类型 + string 与 自增类型转换和赋值类型转换 一.字符串与其他类型连接 public class DemoString{ public static void mai ...
随机推荐
- MySQL服务 - 客户端工具mysql及mysqladmin使用介绍
mysql客户端: mysql工具是MySQL官方提供的连接工具,用户可以通过mysql连接到mysqld上进行一系列的SQL操作.mysql工具有两种模式:交互模式和命令行模式.交互模式指令需要连接 ...
- 关于STM32的FLASH操作【转载】
说到STM32的FLSAH,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装芯片配置.芯片ID.自举程序等等.当然, FLASH还可以用来装数据. FLASH分 ...
- 修改Windows Server 2008+IIS 7+ASP.NET默认连接限制,支持海量并发连接数
WIN7中IIS7默认配置的服务器同时最多只能处理5000个请求,如果由于某些情况(程序问题等)造成同时请求超过5000时,将会导致服务器错误.为此,修改服务器的设置,从而支持10万个同时请求. 具体 ...
- Disruptor 极速体验
已经不记得最早接触到 Disruptor 是什么时候了,只记得发现它的时候它是以具有闪电般的速度被介绍的.于是在脑子里, Disruptor 和"闪电"一词关联了起来,然而却一直没 ...
- git和github使用方式
git 和github github是远程管理代码的服务器的名称 git代码管理系统 (git既然是一个系统,所以说git也有一些命令) git操作过程 首先在本地建立一个仓库,用来把代码提交到git ...
- socket listen参数中的backlog 的意义!
服务器监听时,在每次处理一个客户端的连接时是需要一定时间的,这个时间非常的短(也许只有1ms 或者还不到),但这个时间还是存在的.而这个backlog 存在的意义就是:在这段时间里面除了第一个连接请求 ...
- DELL PowerEdge 2950更换告警硬盘
硬盘为SAS300G15K,四块,3#告警,打算还掉,在R900上找到一块对应的硬盘直接换下. 进入控制台后发现硬盘阵列里还是只有三块硬盘,物理磁盘倒是有四块,新插上的一块状态为“外部”,其他状态是“ ...
- [POJ2096] Collecting Bugs (概率dp)
题目链接:http://poj.org/problem?id=2096 题目大意:有n种bug,有s个子系统.每天能够发现一个bug,属于一个种类并且属于一个子系统.问你每一种bug和每一个子系统都发 ...
- Premier使用笔记
在高中时喜欢打CS,也喜欢看高手的视频,一直打到这游戏淘汰了,为了纪念,也尝试着做了一个视频,就是利用该入门级软件.无意中翻出了当时使用这软件时的笔记,整理到这里,可能这些内容对于博客园来讲太垃圾,毫 ...
- div,li,span自适应宽度换行问题
<ul class="news"> <li><span class="lbl">右对齐,换行显示的解决方法</s ...