摘要:我下圖代碼第五行和第九行分別定義了一個(gè)整型變量和一個(gè)整型常量程序員都知道兩者的區(qū)別。下面我們就用將文件反編譯出來然后深入研究里整型變量和整型常量的區(qū)別。
我下圖代碼第五行和第九行分別定義了一個(gè)整型變量和一個(gè)整型常量:
static final int number1 = 512;
static int number3 = 545;
Java程序員都知道兩者的區(qū)別。
下面我們就用javap將.class文件反編譯出來然后深入研究Java里整型變量和整型常量的區(qū)別。
使用命令行javap -c constant.ConstantFolding查看.class文件反編譯出來的字節(jié)碼:
結(jié)果:
這些字節(jié)碼指令的說明,在wikipedia里有說明:
wiki: https://en.wikipedia.org/wiki...
咱們Java程序員不需要把它們都背下來,只需要把這個(gè)網(wǎng)頁收藏起來,要用的時(shí)候當(dāng)成字典來用就行:
sipush 545: 將整數(shù)545放置到棧上
putstatic #16:
將棧上的值545賦給當(dāng)前類的靜態(tài)字段里。
那么putstatic #16里的#16代表什么含義?
我們再用javap -v 參數(shù)反編譯,就能看到這個(gè)類的常量池(Constant pool). 大家看下圖藍(lán)色高亮的一行:
constant/ConstantFolding.number3:I
說明#16代表類constant.ConstantFolding的成員number3,類型為I。
至此,這兩行字節(jié)碼指令聯(lián)合起來,實(shí)際對應(yīng)了我們寫的Java代碼:
static int number3 = 545;
我們繼續(xù)分析javap反編譯出來的字節(jié)碼。
aload_0: 將序號為0的本地變量的引入加載到棧上
invokespecial: 調(diào)用對象實(shí)例上的成員方法,如果有返回值,方法的返回值存儲(chǔ)到棧上。具體調(diào)用的方法由#標(biāo)識(shí),可在常量池中查詢到對應(yīng)的方法名。
ldc: 將常量池上代號為#<數(shù)字>的常量的值從常量池加載到棧上。
我們從下圖的常量池列表能發(fā)現(xiàn),序號為#29的常量318976正是整型常量number1(512)和整型常量(623)的積。由此可以看出, number1 * number2這個(gè)表達(dá)式,因?yàn)閰⑴c運(yùn)算的兩個(gè)操作數(shù)通過STATIC和FINAL修飾成為了整型常量,因此其積在編譯期就能得到,所以編譯器在編譯時(shí)就計(jì)算出來,存儲(chǔ)在變量池里,序號為#29。
那么整型變量做乘法運(yùn)算,對應(yīng)的字節(jié)碼又是什么樣的呢?
從下圖序號為3的code開始:
getstatic #16: 將類的靜態(tài)成員#16加載到棧上。#16對應(yīng)的成員為number3,值為545。
getstatic #18: 將類的靜態(tài)成員#18加載到棧上。#18對應(yīng)的成員為number4,值為619。
imul: 執(zhí)行棧上兩個(gè)整數(shù)的乘法運(yùn)算。
istore_2: 將結(jié)果保存到局部變量2里。
此時(shí),我們Java代碼里的int product2 = number3 * number4就執(zhí)行完了。
大家看到的剩下的藍(lán)色字節(jié)碼,都對應(yīng)了下面這行打印語句。
System.out.println("Value: " + product1 + " , " + product2);
從這些字節(jié)碼也能看出,Java里我們直接用加號進(jìn)行字符串拼接操作,Java編譯器在編譯時(shí),自動(dòng)使用了StringBuilder進(jìn)行優(yōu)化。
既然整型變量的乘積需要打印出來,因此字節(jié)碼的iload_2將之前用istore_2保存在局部變量2中的計(jì)算結(jié)果又加載到棧上,這樣乘積結(jié)果最后就能輸出了。
希望通過這個(gè)簡單的例子,大家能學(xué)會(huì)用javap去深入理解一些Java和JVM的細(xì)節(jié)。
要獲取更多Jerry的原創(chuàng)技術(shù)文章,請關(guān)注公眾號"汪子熙"或者掃描下面二維碼:
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/71812.html
摘要:本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接智能合約語言教程系列地址類型介紹原文已更新,請讀者前往原文閱讀現(xiàn)在的中文文檔,要么翻譯的太爛,要么太舊,決定重新翻譯下。枚舉類型應(yīng)至少有一名成員。 本文首發(fā)于深入淺出區(qū)塊鏈社區(qū)原文鏈接:智能合約語言 Solidity 教程系列2 - 地址類型介紹原文已更新,請讀者前往原文閱讀 現(xiàn)在的Solidity中文文檔,要么翻譯的太爛,要么太舊,決定重新翻譯下。...
摘要:目錄往期博客課堂篇初識(shí)常量池簡單理解字符串常量池靜態(tài)常量池大整型常量池為什么要了解垃圾收集和內(nèi)存分配如何判斷對象已死引用計(jì)數(shù)算法可達(dá)性分析算法之后引用的擴(kuò)充回收方法區(qū)垃圾收集算法分代收集理論標(biāo)記清除標(biāo)記復(fù)制標(biāo)記整理對象分 ...
摘要:數(shù)據(jù)的存儲(chǔ)前言數(shù)據(jù)類型匯總整型家族浮點(diǎn)型家族自定義類型指針類型。整型家族注在之后的標(biāo)準(zhǔn)規(guī)定,將類型數(shù)據(jù)劃分為整型家族,因?yàn)樽址趦?nèi)存中會(huì)將其轉(zhuǎn)化為碼值進(jìn)行存儲(chǔ)。 ...
摘要:結(jié)構(gòu)型模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。行為型模式模版方法模式命令模式迭代器模式觀察者模式中介者模式備忘錄模式解釋器模式模式狀態(tài)模式策略模式職責(zé)鏈模式責(zé)任鏈模式訪問者模式。 主要版本 更新時(shí)間 備注 v1.0 2015-08-01 首次發(fā)布 v1.1 2018-03-12 增加新技術(shù)知識(shí)、完善知識(shí)體系 v2.0 2019-02-19 結(jié)構(gòu)...
摘要:文章來自原文在給開發(fā)者的源碼系列的第三篇文章,我們打算擴(kuò)展上一篇文章來幫助理解內(nèi)部是怎么工作的。進(jìn)入在的核心代碼中,變量被稱為。要轉(zhuǎn)換一個(gè)為值,就調(diào)用函數(shù)。有了這個(gè)東西,我們可以看到函數(shù)馬上調(diào)用函數(shù)。 文章來自:http://www.hoohack.me/2016/02/12/phps-source-code-for-php-developers-part3-variables-ch...
閱讀 849·2021-11-15 17:58
閱讀 3648·2021-11-12 10:36
閱讀 3786·2021-09-22 16:06
閱讀 959·2021-09-10 10:50
閱讀 1327·2019-08-30 11:19
閱讀 3313·2019-08-29 16:26
閱讀 934·2019-08-29 10:55
閱讀 3344·2019-08-26 13:48