Java字節(jié)碼深入解析
一:Java字節(jié)代碼的組織形式
類(lèi)文件{
OxCAFEBABE,小版本號(hào),大版本號(hào),常量池大小,常量池?cái)?shù)組,訪問(wèn)控制標(biāo)記,當(dāng)前類(lèi)信息,父類(lèi)信息,實(shí)現(xiàn)的接口個(gè)數(shù),實(shí)現(xiàn)的接口信息數(shù)組,域個(gè)數(shù),域信息數(shù)組,方法個(gè)數(shù),方法信息數(shù)組,屬性個(gè)數(shù),屬性信息數(shù)組
}
二:查看方法 --- javap命令
例子:有一個(gè)Java類(lèi)Demo.java
通過(guò)jdk自帶的反編譯工具命令 javap 可以查看class文件的字節(jié)碼信息
D:\>javap -verbose Demo >> Demo.txt |
Demo.txt:
解析:
1、版本號(hào) major version: 49 //java版本 jdk1.6顯示的是50, jdk1.5顯示的是49,jdk1.4顯示的是58 , 高版本能執(zhí)行低版本的class文件
2、常量池Constant pool
Method:方法
Field:字段
String:字符串
Asciz:簽名如<init>由jvm調(diào)用,其他是不能夠去調(diào)用它的
NameAndType:變量名的類(lèi)型
Class:類(lèi)
通過(guò)字節(jié)碼,我們可以看到Demo類(lèi) 繼承于java.lang.Object,如果類(lèi)中沒(méi)有顯式聲明構(gòu)造函數(shù)的話(huà),編譯器會(huì)插入一個(gè)缺省無(wú)參的構(gòu)造函數(shù)(構(gòu)造函數(shù)在JVM級(jí)別是顯示成<init>的普通函數(shù))。
三:檢測(cè)代碼的效率問(wèn)題
學(xué)習(xí)Java的過(guò)程中,都會(huì)了解到字符串合并時(shí)要用到StringBuffer 來(lái)代替String,那下面就來(lái)通過(guò)Java字節(jié)碼來(lái)驗(yàn)證兩種方式的效率性。
例子:一個(gè)Java類(lèi) TestString.java
javap –c TestString 后字節(jié)碼信息:
從上面編譯后的字節(jié)碼信息可以看出來(lái),方法testString 調(diào)用了五個(gè)方法:new 、invokestatic 、invokespecial 和兩個(gè)invokevirtual ; 而testStringBuffer 方法只調(diào)用了兩個(gè)invokevirtual 方法。第一個(gè)方法比第二個(gè)方法多做了好多工作,其效率當(dāng)然是要低的。而且我們從java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
可以看出來(lái)其實(shí)對(duì)于String字符串合并,內(nèi)部還是轉(zhuǎn)化為StringBuilder的方法調(diào)用,這是因?yàn)镾tring是長(zhǎng)度不可變的,所以不如直接采用StringBuilder(與StringBuffer 長(zhǎng)度都是可變的,只不過(guò)前者是非線(xiàn)程安全,后者是線(xiàn)程安全)進(jìn)行字符串合并。
posted on 2011-12-06 11:10 順其自然EVO 閱讀(7944) 評(píng)論(0) 編輯 收藏