轉自https://blog.csdn.net/lovepluto/article/details/81062176

如果問 a++ 和 ++a 的區別,估計很多都能回答上來。a++ 是先取 a 的值再自增 。而 ++a 剛好相反,是先自增再取 a 的值。這里有點編程基礎都可以理解,不做過多解釋,但在 Java 里面事情就真的這么簡單嗎?

int a = 1;

a = a++;

System.out.println(a);

憑借自己所學,在不測試的情況下,你能給出答案嗎?

第一次看見這個問題的時候,想當然的認為答案是:2。但殘酷的事實告訴我,答案是:1。當時面對這個結果我是無法接受的,網上瘋狂搜索這個答案的解釋。限於當時知識的水平,只記住了這個結論,至於推導這個結論那些指令,一個也不能理解。今天看書遇見數據操作,就又想起了這個問題,就根據自己的知識水平,重新推導這個過程。

首先用 IDEA 打開生成的 class 文件。

很直觀的告訴我們結果為 1 ,但這段代碼只解釋了 result,而沒有解釋 why ,繼續用 javap -c 這個命令,結果如圖。

以第一次遇見這道題的水准,勉強能看懂第一步的 Java 代碼,第二步的指令就徹底看不懂了。而現在我可以從這些指令里面分析結果了(這里需要分析的就前五行命令,后面指令為打印輸出)。

iconst_1

將常量 1 壓入操作數棧。這個操作是 int 值為 1~5 的時候。如果是 -128~127 這個范圍是用的 bipush x (x 為實際數值)。 -2^15~2^15-1 這個范圍是使用的 sipush x 這個命令(同上)。 -2^31~2^31-1 這個范圍是使用的 ldc 這個命令。

istore_1

彈出操作數棧頂的數(此時為 1)並賦值給局部變量第一個元素即索引為 1 的 a。局部變量是采用的數組形式,索引為 0 的是 main() 的參數 args 。

iload_1

把局部變量索引為 1 的變量(這里是 a)壓入操作數棧,此時棧頂元素為 1 。

incc 1,1(關鍵)

把局部變量索引為 1 的數加 1 ,此時 a 的值為 2。注意:這個結果沒有壓入操作數棧。

istore_1

彈出棧頂的元素(此時為 1)賦值給 a ,覆蓋 a 為 2 的結果。

整個過程大致就是這樣,來一幅圖解釋吧。

這個問題解決了,那么下面這段代碼就好理解了。

int a = 1;

a = ++a;

System.out.println(a);

直接上截圖吧

仔細對比一下,你會發現,兩段代碼的指令一模一樣,但執行順序有一點點區別, iinc 和 iload_1 這兩個命令的執行順序變化了一下位置。你還記得這兩條指令的含義嗎?你還記得文章最開始說的區別嗎?

java中a 和 a_Java中a=a++ 和 a=++a(轉)相关推荐

  1. java static int a_java中static作用详解

    static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static ...

  2. java变量存储位置_java 中变量存储位置的区别

    [原文] 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量 ...

  3. springboot yml怎么建常量_【Java】SpringBoot 中从application.yml中获取自定义常量

    由于这里我想通过java连接linux,connection连接需要host.port.username.password及其他路径等等.不想每次修改的时候都去改源文件,所以想写在applicatio ...

  4. Java:判断一个字符串中是否存在另一个字符子串以及判断一个字符串中是否存在指定字符

    Java:判断一个字符串中包含指定字符子串,判断一个字符串中存在指定字符 字符串的contains方法可以判断一个字符串中是否存在另一个字符子串,示例如下 String Str = "Hel ...

  5. java获取jsp页面参数_jsp页面中获取servlet请求中的参数方法总结

    jsp页面中获取servlet请求中的参数的办法详解 在JAVA WEB应用中,如何获取servlet请求中的参数,并传递给跳转的JSP页面?例如访问http://localhost:8088/bbs ...

  6. JAVA中循环删除list中元素的方法总结

    原文:http://www.cnblogs.com/aspirant/p/7900854.html 印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天 ...

  7. Java 项目JDBC 链接数据库中会出现的错误

    1.出现的地方 1 package com.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 impor ...

  8. 每个java程序都至少有一个线程给主线程,java程序在主线程中判断各个子线程状态的操作,该如何解决...

    java程序在主线程中判断各个子线程状态的操作 每个子线程在队列为空时会wait等待其他线程添加新url到队列,到最后所有子线程都取不到url时也会都wait住,要在主线程中判断如果所有的子线程都是w ...

  9. junit5_在Java 8之前的项目中使用JUnit 5

    junit5 这篇文章演示了如何在Java 8之前的项目中使用JUnit 5,并解释了为什么它是一个好主意. JUnit 5至少需要Java 8作为运行时环境,因此您想将整个项目更新为Java8.但是 ...

最新文章

  1. C# winform中MouseDoubleClick与DoubleClick的区别
  2. 旋转矩阵和角速度的一些应用
  3. 英语美句-每日积累-02
  4. kicad最小布线宽度默认是多少_你想知道建仓库时叉车通道宽度留多少吗?
  5. 用计算机弹奏曲子童年,5.这首曲子使我想起了我的童年.十.书面表达现在.计算机游戏非常盛行.这是一件好事还是一件坏事?请你用英语写一篇短文来陈述自己的观点.并说明理由.字数:80-120....
  6. 【离散数学】图的着色与对偶图
  7. Qt文档阅读笔记-QWebEngineView及QML WebEngineView
  8. 传智播客pscs6ppt_freeCodeCamp播客直播。 这是6集,您现在可以狂欢。
  9. 9.python-匿名函数(lambda)
  10. SpringBoot使用@Scheduled创建定时任务
  11. unity4.x从入门到精通、Unity 5.x游戏开发指南读书摘要(2015-4-21 12:10、2015-12-28 22:12)
  12. Linux 通配符 与 正则表达式 的区别与详解
  13. 三阶龙格库塔matlab,三阶、四阶龙格库塔函数matlab代码.doc
  14. 物联网之有线通信技术之短距离的现场总线
  15. TS进阶之infer
  16. 谷歌浏览器 Chrome 安装 Tampermonkey 油猴插件的方法
  17. kubernetes资源管理平台ratel
  18. NSWindow纯代码设置
  19. Python鼠标点击图片,获取点击点的像素坐标/像素值
  20. 史玉柱和郭广昌谈创业团队管理:两种类型的“孔雀王”

热门文章

  1. git reset --mixed, - soft和--hard有什么区别?
  2. 如何连接(合并)数据框(内部,外部,左侧,右侧)
  3. win11小组件怎么卸载 windows11卸载小组件的步骤方法
  4. Python基础-循环
  5. passwd: 鉴定令牌操作错误_user 及passwd 设置
  6. 机器人参数校准的原理
  7. qtable sorting enable中文是按照什么顺序_作为雅思过来人,你有什么话想告诫雅思小白的?...
  8. JavaScript中的(字符串,数字型,布尔型)是如何实现类型转换的?
  9. C# Object与二进制串(byte数组)之间的转换
  10. token的作用_说一说Coin和Token有什么不同