日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

深入理解Java Class文件格式(二)

 看風(fēng)景D人 2016-10-07


在上一篇文章 深入理解Java Class文件格式(一) 中, 介紹了class文件在整個(gè)Java體系結(jié)構(gòu)中的位置和作用, 并對(duì)class文件的整體格式做了說(shuō)明, 介紹了其中的魔數(shù)和版本號(hào)的相關(guān)內(nèi)容, 并對(duì)常量池做了概述。 在本文章, 繼續(xù)介紹class文件中的其他內(nèi)容。


class文件中的特殊字符串


首先說(shuō)明一下, 所謂的特殊字符串出現(xiàn)在class文件中的常量池中, 所以在上一篇博客中, 只是對(duì)常量池介紹了一個(gè)大概。 本著循序漸進(jìn)和減少跨度的原則, 首先把class文件中的特殊字符串做一個(gè)詳細(xì)的介紹, 然后再回過(guò)頭來(lái)繼續(xù)講解常量池。 

在上文中, 我們提到特殊字符串是常量池中符號(hào)引用的一部分, 至于符號(hào)引用的概念, 會(huì)在以后提到。 現(xiàn)在我們將重點(diǎn)放在特殊字符串上。 特殊字符串包括三種: 類的全限定名, 字段和方法的描述符, 特殊方法的方法名。 下面我們就分別介紹這三種特殊字符串。

(1) 類的全限定名


在常量池中, 一個(gè)類型的名字并不是我們?cè)谠次募锌吹降哪菢樱?也不是我們?cè)谠次募惺褂玫陌宇惷男问健?源文件中的全限定名和class文件中的全限定名不是相同的概念。 源文件中的全新定名是包名加類名, 包名的各個(gè)部分之間,包名和類名之間, 使用點(diǎn)號(hào)分割。 如Object類, 在源文件中的全限定名是java.lang.Object 。 而class文件中的全限定名是將點(diǎn)號(hào)替換成“/” 。 例如, Object類在class文件中的全限定名是 java/lang/Object 。 如果讀者之前沒(méi)有接觸過(guò)class文件格式, 是class文件格式的初學(xué)者, 在這里不必知道全限定名在class文件中是如何使用的, 只需要知道, 源文件中一個(gè)類的名字, 在class文件中是用全限定名表述的。 

(2) 描述符


我們知道在一個(gè)類中可以有若干字段和方法, 這些字段和方法在源文件中如何表述, 我們?cè)偈煜げ贿^(guò)了。 既然現(xiàn)在我們要學(xué)習(xí)class文件格式, 那么我們就要問(wèn), 一個(gè)字段或一個(gè)方法在class文件中是如何表述的? 在本文中, 我們會(huì)討論方法和字段在class文件中的描述。 方法和字段的描述符并不會(huì)把方法和字段的所有信息全都描述出來(lái), 畢竟描述符只是一個(gè)簡(jiǎn)單的字符串。 

在講解描述符之前, 要先說(shuō)明一個(gè)問(wèn)題, 那就是所有的類型在描述符中都有對(duì)應(yīng)的字符或字符串來(lái)對(duì)應(yīng)。 比如, 每種基本數(shù)據(jù)類型都有一個(gè)大寫字母做對(duì)應(yīng), void也有一個(gè)大寫字符做對(duì)應(yīng)。 下表是void和基本數(shù)據(jù)類型在描述符中的對(duì)應(yīng)。

基本數(shù)據(jù)類型和void類型 類型的對(duì)應(yīng)字符
byte B
char C
double D
float F
int I
long J
short S
boolean Z
void V


基本上都是以類型的首字符變成大寫來(lái)對(duì)應(yīng)的, 其中l(wèi)ong和boolean是特例, long類型在描述符中的對(duì)應(yīng)字符是J, boolean類型在描述符中的對(duì)應(yīng)字符是Z 。 

基本類型和void在描述符中都有一個(gè)大寫字符和他們對(duì)應(yīng), 那么引用類型(類和接口,枚舉)在描述符中是如何對(duì)應(yīng)的呢? 引用類型的對(duì)應(yīng)字符串(注意, 引用類型在描述符中使用一個(gè)字符串做對(duì)應(yīng)) , 這個(gè)字符串的格式是:

[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. “L” + 類型的全限定名 + “;”  

注意,這三個(gè)部分之間沒(méi)有空格, 是緊密排列的。 如Object在描述符中的對(duì)應(yīng)字符串是: Ljava/lang/Object;  ; ArrayList在描述符中的對(duì)應(yīng)字符串是: Ljava/lang/ArrayList;  ; 自定義類型com.example.Person在描述符中的對(duì)應(yīng)字符串是: Lcom/example/Person; 。

我們知道, 在Java語(yǔ)言中數(shù)組也是一種類型, 一個(gè)數(shù)組的元素類型和他的維度決定了他的類型。 比如, 在 int[] a 聲明中, 變量a的類型是int[] , 在 int[][] b 聲明中, 變量b的類型是int[][] , 在 Object[] c 聲明中, 變量c的類型是Object[] 。既然數(shù)組是類型, 那么在描述符中, 也應(yīng)該有數(shù)組類型的對(duì)應(yīng)字符串。 在class文件的描述符中, 數(shù)組的類型中每個(gè)維度都用一個(gè) [ 代表, 數(shù)組類型整個(gè)類型的對(duì)應(yīng)字符串的格式如下:

[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. 若干個(gè)“[”  +  數(shù)組中元素類型的對(duì)應(yīng)字符串   

下面舉例來(lái)說(shuō)名。 int[]類型的對(duì)應(yīng)字符串是: [I  。 int[][]類型的對(duì)應(yīng)字符串是: [[I 。 Object[]類型的對(duì)應(yīng)字符串是: [Ljava/lang/Object; 。 Object[][][]類型的對(duì)應(yīng)字符串是: [[[Ljava/lang/Object; 。

介紹完每種類型在描述符中的對(duì)應(yīng)字符串, 下面就開始講解字段和方法的描述符。 

字段的描述符就是字段的類型所對(duì)應(yīng)的字符或字符串。 如: int i 中, 字段i的描述符就是 I 。 Object o中, 字段o的描述符就是 Ljava/lang/Object;  。 double[][] d中, 字段d的描述符就是 [[D 。 

方法的描述符比較復(fù)雜, 包括所有參數(shù)的類型列表和方法返回值。 它的格式是這樣的:

[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. (參數(shù)1類型 參數(shù)2類型 參數(shù)3類型 ...)返回值類型  

其中, 不管是參數(shù)的類型還是返回值類型, 都是使用對(duì)應(yīng)字符和對(duì)應(yīng)字符串來(lái)表示的, 并且參數(shù)列表使用小括號(hào)括起來(lái), 并且各個(gè)參數(shù)類型之間沒(méi)有空格, 參數(shù)列表和返回值類型之間也沒(méi)有空格。 

下面舉例說(shuō)明(此表格來(lái)源于《深入Java虛擬機(jī)》)。

方法描述符 方法聲明
()I int getSize()
()Ljava/lang/String; String toString()
([Ljava/lang/String;)V void main(String[] args)
()V void wait()
(JI)V void wait(long timeout, int nanos)
(ZILjava/lang/String;II)Z boolean regionMatches(boolean ignoreCase, int toOffset, String other, int ooffset, int len)
([BII)I int read(byte[] b, int off, int len )
()[[Ljava/lang/Object; Object[][] getObjectArray()

 

(3) 特殊方法的方法名


首先要明確一下, 這里的特殊方法是指的類的構(gòu)造方法和類型初始化方法。 構(gòu)造方法就不用多說(shuō)了, 至于類型的初始化方法, 對(duì)應(yīng)到源碼中就是靜態(tài)初始化塊。 也就是說(shuō), 靜態(tài)初始化塊, 在class文件中是以一個(gè)方法表述的, 這個(gè)方法同樣有方法描述符和方法名。 

類的構(gòu)造方法的方法名使用字符串 <init> 表示, 而靜態(tài)初始化方法的方法名使用字符串 <clinit> 表示。 除了這兩種特殊的方法外, 其他普通方法的方法名, 和源文件中的方法名相同。


總結(jié)


到此為止, 關(guān)于特殊字符串就講解完了。 最后做一下總結(jié):

class文件中的特殊字符串包括類(包括接口, 枚舉)的全限定名, 字段的描述符和方法的描述符。 其中類的全限定名比較簡(jiǎn)單易于理解, 字段和方法的描述符由于涉及到每種類型的映射, 可能稍顯復(fù)雜。 要理解描述符, 主要是要熟記每種類型(包括8種基本數(shù)據(jù)類型,類類型, 數(shù)組類型和void)在描述符中所對(duì)應(yīng)的描述字符或字符串。 

還有一點(diǎn)需要注意, 就是方法和字段的描述符中, 不包括字段名和方法名, 字段描述符中只包括字段類型, 方法描述符中只包括參數(shù)列表和返回值類型。 

本文只是介紹class中的特殊字符串, 關(guān)于在class文件中如何使用這些字符串, 將會(huì)在下一篇博客中講解, 敬請(qǐng)關(guān)注。 



更多關(guān)于深入理解Java的文章, 請(qǐng)關(guān)注我的專欄 : http://blog.csdn.net/column/details/zhangjg-java-blog.html

更多關(guān)于Java和Android等其他技術(shù)的文章, 請(qǐng)關(guān)注我的博客: http://blog.csdn.net/zhangjg_blog

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多