這章的一個(gè)例子雖然簡單,但是我覺的很有一定代表性。例子如下: 1:class Act { 2: public static void doMathForever(int m) { 3: int i = 0; 4: int n=4>3?1:0; 5: for (;;) { 6: i += 1; 7: i *= 2; 8: } 9: } 10:} 我用javap -verbose Act查看,代碼如下:(紅色為自己加上的注解) Compiled from "Act.java" 因 為編譯原文件不一定必須與java語言相關(guān),可以使用其他語言來編寫程序,然后將其編譯為class文件,所以這里要寫上Act.java而不是Act. 呵呵,想來以前為什么javac 來編譯源文件時(shí)一定要加.java,而java 執(zhí)行時(shí)就不需要加.java了,當(dāng)時(shí)就是搞不懂,現(xiàn)在明白了。 class Act extends java.lang.Object SourceFile: "Act.java" SourceFile屬性,它提供了產(chǎn)生class文件的源文件的名稱,它是一個(gè)可選的項(xiàng),為什么說它是可選項(xiàng)的,因?yàn)閏lass可以自己用UE等工具寫。 minor version: 0 major version: 49 版本號(hào):我用的是5.0的,出來的major version 是49,書上說1.0或1.2是45,1.4我想可能是48 吧。呵呵,還沒有試過。 Constant pool: 這個(gè)是常量池,剛看書的時(shí)候我還以為常量池放的一定是常量。錯(cuò)。 常量池就是該類型所用常量的一個(gè)有序集合,包括直接常量(String,integer,floating point常量)和對(duì)其他類型、字段和方法的符號(hào)引用。 const #1 = Method #3.#12; // java/lang/Object."<init>":()V 因?yàn)镃onstant pool#0是不用的,所以只能從#1開始,但不知為什么第一個(gè)是Method而不是class,我現(xiàn)在還不明白。 const #2 = class #13; // Act CONSTANT_Class是對(duì)一個(gè)類或接口的符號(hào)引用。這個(gè)是指向#13 const #3 = class #14; // java/lang/Object const #4 = Asciz <init>; 這個(gè)Asciz應(yīng)該表示是CONSTANT_Utf8吧,因?yàn)镃 ONSTANT_Utf8可以是存儲(chǔ)四種基本信息類型:文字字符串、被定義的類和接口描述、對(duì)其他類或接口的符號(hào)引用以及屬性相關(guān)的字符串。 <init>是實(shí)例的初始化方法,是實(shí)例調(diào)用方法前必須要<init>的, <clinit>是類的初始化方法。 const #5 = Asciz ()V; 此<init>的描述符,()V表示<init>沒有帶參數(shù),返回的是void型的。 書上介紹: ()I int getSize() () Ljava/lang/String String toString() const #6 = Asciz Code; Code在所有不是抽象或者本地方法的method_info信息中,都存在一個(gè)Code_attribute表。 但是我試一下在抽象的方法中同樣也有code的啊,不懂中。 const #7 = Asciz LineNumberTable; LineNumberTable屬性建立了方法字節(jié)碼流偏移量和源代碼行號(hào)之間的映射關(guān)系。關(guān)于這一點(diǎn),我在下面詳細(xì)談到。 const #8 = Asciz doMathForever; #8 字段名和方法名以簡單名稱出現(xiàn)在常量池的入口中,存的時(shí)候存簡單名字,調(diào)用的時(shí)候要加 上全限定名 const #9 = Asciz (I)V; doMathForover的描述符,參數(shù)是int類型,返回值是void類型 const #10 = Asciz SourceFile; const #11 = Asciz Act.java; const #12 = NameAndType #4:#5;// "<init>":()V NameAndType指向字段或者方法的符號(hào)引用的一部分。為什么沒有指向#8,#9呢?不懂中。 const #13 = Asciz Act; const #14 = Asciz java/lang/Object;
#13,#14
CONSTANT_Utf8_info 表的入口,容納了 類/接口全限定名等信息。用“/”代替“.”。在class文件的this_class字段是
對(duì)常量池的一個(gè)引用,指向了常量池中CONSTANT_ClASS_info表,該表由兩項(xiàng)組成,即標(biāo)簽和name_index。在這個(gè)例子
里,this_class的值為2,也就是常量池里的第二項(xiàng),這項(xiàng)標(biāo)簽是class,name_index是13,即指向常量池的第13項(xiàng)。第13項(xiàng)里就
有當(dāng)前類的全限定名。
public static void doMathForever(int); } |
|