您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java字節(jié)碼實(shí)例分析”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Java字節(jié)碼實(shí)例分析”吧!
一:Java字節(jié)代碼的組織形式
類文件{
OxCAFEBABE,小版本號(hào),大版本號(hào),常量池大小,常量池?cái)?shù)組,訪問控制標(biāo)記,當(dāng)前類信息,父類信息,實(shí)現(xiàn)的接口個(gè)數(shù),實(shí)現(xiàn)的接口信息數(shù)組,域個(gè)數(shù),域信息數(shù)組,方法個(gè)數(shù),方法信息數(shù)組,屬性個(gè)數(shù),屬性信息數(shù)組
}
二:查看方法 --- javap命令
例子:有一個(gè)Java類Demo.java
public class Demo { private String str1; private String str2; private int num1; private int num2; public static final String STATIC_DATA = "hello world"; private void sayHello1(){ System.out.println("this is method1..."); } private void sayHello2(){ System.out.println("this is method2..."); } public void sayHello3(){ System.out.println("this is method3..."); } }
通過jdk自帶的反編譯工具命令 javap 可以查看class文件的字節(jié)碼信息
D:\>javap -verbose Demo >> Demo.txt
Demo.txt:
Compiled from "Demo.java" public class Demo extends java.lang.Object SourceFile: "Demo.java" minor version: 0 major version: 49 Constant pool: const #1 = class #2; // Demo const #2 = Asciz Demo; const #3 = class #4; // java/lang/Object const #4 = Asciz java/lang/Object; const #5 = Asciz str1; const #6 = Asciz Ljava/lang/String;; const #7 = Asciz str2; const #8 = Asciz num1; const #9 = Asciz I; const #10 = Asciz num2; const #11 = Asciz STATIC_DATA; const #12 = Asciz ConstantValue; const #13 = String #14; // hello world const #14 = Asciz hello world; const #15 = Asciz <init>; const #16 = Asciz ()V; const #17 = Asciz Code; const #18 = Method #3.#19; // java/lang/Object."<init>":()V const #19 = NameAndType #15:#16;// "<init>":()V const #20 = Asciz LineNumberTable; const #21 = Asciz LocalVariableTable; const #22 = Asciz this; const #23 = Asciz LDemo;; const #24 = Asciz sayHello1; const #25 = Field #26.#28; // java/lang/System.out:Ljava/io/PrintStream; const #26 = class #27; // java/lang/System const #27 = Asciz java/lang/System; const #28 = NameAndType #29:#30;// out:Ljava/io/PrintStream; const #29 = Asciz out; const #30 = Asciz Ljava/io/PrintStream;; const #31 = String #32; // this is method1... const #32 = Asciz this is method1...; const #33 = Method #34.#36; // java/io/PrintStream.println:(Ljava/lang/String;)V const #34 = class #35; // java/io/PrintStream const #35 = Asciz java/io/PrintStream; const #36 = NameAndType #37:#38;// println:(Ljava/lang/String;)V const #37 = Asciz println; const #38 = Asciz (Ljava/lang/String;)V; const #39 = Asciz sayHello2; const #40 = String #41; // this is method2... const #41 = Asciz this is method2...; const #42 = Asciz sayHello3; const #43 = String #44; // this is method3... const #44 = Asciz this is method3...; const #45 = Asciz SourceFile; const #46 = Asciz Demo.java; { public static final java.lang.String STATIC_DATA; Constant value: String hello world public Demo(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #18; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 2: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LDemo; public void sayHello3(); Code: Stack=2, Locals=1, Args_size=1 0: getstatic #25; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #43; //String this is method3... 5: invokevirtual #33; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 17: 0 line 18: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 this LDemo; }
解析:
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:變量名的類型
Class:類
通過字節(jié)碼,我們可以看到Demo類 繼承于java.lang.Object,如果類中沒有顯式聲明構(gòu)造函數(shù)的話,編譯器會(huì)插入一個(gè)缺省無(wú)參的構(gòu)造函數(shù)(構(gòu)造函數(shù)在JVM級(jí)別是顯示成<init>的普通函數(shù))。
三:檢測(cè)代碼的效率問題
學(xué)習(xí)Java的過程中,都會(huì)了解到字符串合并時(shí)要用到StringBuffer 來(lái)代替String,那下面就來(lái)通過Java字節(jié)碼來(lái)驗(yàn)證兩種方式的效率性。
例子:一個(gè)Java類 TestString.java
<strong>public class TestString { public String testString(String str1, String str2){ return str1 + str2; } public String testStringBuffer(StringBuffer sb, String str){ return sb.append(str).toString(); } } </strong>
javap –c TestString 后字節(jié)碼信息:
Compiled from "TestString.java" public class TestString extends java.lang.Object{ public TestString(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return public java.lang.String testString(java.lang.String, java.lang.String); Code: 0: new #16; //class java/lang/StringBuilder 3: dup 4: aload_1 5: invokestatic #18; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 8: invokespecial #24; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 11: aload_2 12: invokevirtual #27; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: invokevirtual #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 18: areturn public java.lang.String testStringBuffer(java.lang.StringBuffer, java.lang.String); Code: 0: aload_1 1: aload_2 2: invokevirtual #40; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer; 5: invokevirtual #45; //Method java/lang/StringBuffer.toString:()Ljava/lang/String; 8: areturn }
從上面編譯后的字節(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)度都是可變的,只不過前者是非線程安全,后者是線程安全)進(jìn)行字符串合并。
感謝各位的閱讀,以上就是“Java字節(jié)碼實(shí)例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Java字節(jié)碼實(shí)例分析這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。