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

分享

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

 看風(fēng)景D人 2016-10-07
一個(gè)常量池中的CONSTANT_Float_info數(shù)據(jù)項(xiàng), 可以看做是CONSTANT_Float類型的一個(gè)實(shí)例。 它存儲(chǔ)的是源文件中出現(xiàn)的float型數(shù)據(jù)的值。 同樣, 作為常量池中的一種數(shù)據(jù)類型, 它的第一個(gè)字節(jié)也是一個(gè)tag值, 它的tag值為4, 也就是說(shuō), 當(dāng)虛擬機(jī)讀到一個(gè)tag值為4的數(shù)據(jù)項(xiàng)時(shí), 就知道這個(gè)數(shù)據(jù)項(xiàng)是一個(gè)CONSTANT_Float_info, 并且知道它存儲(chǔ)的是float型數(shù)值。 緊挨著tag的下面4個(gè)字節(jié)叫做bytes, 就是float型的數(shù)值。 它的內(nèi)存布局如下:


舉例說(shuō)明, 如果源文件中的一句代碼使用了一個(gè)float值, 如下所示:
  1. void printFloat(){  
  2.     System.out.println(1234.5f);  
  3. }  

那么在這個(gè)類的常量池中就會(huì)有一個(gè)CONSTANT_Float_info與之相對(duì)應(yīng), 這個(gè)CONSTANT_Float_info的形式如下:



代碼反編譯結(jié)果如下:
[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. Constant pool:  
  2.   
  3. .............  
  4. .............  
  5.   
  6.   #29 = Float              1234.5f  
  7.   
  8. ............  
  9. ............  
  10.   
  11. {  
  12.   
  13. ............  
  14. ............  
  15.   
  16.   void printFloat();  
  17.     flags:  
  18.     Code:  
  19.       stack=2, locals=1, args_size=1  
  20.          0: getstatic     #15                 // Field java/lang/System.out:Ljava/io/PrintStream;  
  21.          3: ldc           #29                 // float 1234.5f  
  22.          5: invokevirtual #30                 // Method java/io/PrintStream.println:(F)V  
  23.          8: return  
  24.       LineNumberTable:  
  25.         line 10: 0  
  26.         line 11: 8  
  27.       LocalVariableTable:  
  28.         Start  Length  Slot  Name   Signature  
  29.                0       9     0  this   Lcom/jg/zhang/TestInt;  
  30. }  


(5)CONSTANT_Long_info


一個(gè)常量池中的CONSTANT_Long_info數(shù)據(jù)項(xiàng), 可以看做是CONSTANT_Long類型的一個(gè)實(shí)例。 它存儲(chǔ)的是源文件中出現(xiàn)的long型數(shù)據(jù)的值。 同樣, 作為常量池中的一種數(shù)據(jù)類型, 它的第一個(gè)字節(jié)也是一個(gè)tag值, 它的tag值為5, 也就是說(shuō), 當(dāng)虛擬機(jī)讀到一個(gè)tag值為5的數(shù)據(jù)項(xiàng)時(shí), 就知道這個(gè)數(shù)據(jù)項(xiàng)是一個(gè)CONSTANT_Long_info, 并且知道它存儲(chǔ)的是long型數(shù)值。 緊挨著tag的下面8個(gè)字節(jié)叫做bytes, 就是long型的數(shù)值。 它的內(nèi)存布局如下:


舉例說(shuō)明, 如果源文件中的一句代碼使用了一個(gè)long型的數(shù)值, 如下所示:
  1. void printLong(){  
  2.     System.out.println(123456L);  
  3. }  

那么在這個(gè)類的常量池中就會(huì)有一個(gè)CONSTANT_Long_info與之相對(duì)應(yīng), 這個(gè)CONSTANT_Long_info的形式如下:


代碼反編譯結(jié)果為:
[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. Constant pool:  
  2.   
  3. ..............  
  4. ..............  
  5.   
  6.   #21 = Long               123456l  
  7.   
  8. ..............  
  9. ..............  
  10.   
  11. {  
  12.   
  13. ..............  
  14. ..............  
  15.   
  16.   void printLong();  
  17.     flags:  
  18.     Code:  
  19.       stack=3, locals=1, args_size=1  
  20.          0: getstatic     #15                 // Field java/lang/System.out:Ljava/io/PrintStream;  
  21.          3: ldc2_w        #21                 // long 123456l  
  22.          6: invokevirtual #23                 // Method java/io/PrintStream.println:(J)V  
  23.          9: return  
  24.       LineNumberTable:  
  25.         line 7: 0  
  26.         line 8: 9  
  27.       LocalVariableTable:  
  28.         Start  Length  Slot  Name   Signature  
  29.                0      10     0  this   Lcom/jg/zhang/TestInt;  
  30. }  


(6)CONSTANT_Double_info


一個(gè)常量池中的CONSTANT_Double_info數(shù)據(jù)項(xiàng), 可以看做是CONSTANT_Double類型的一個(gè)實(shí)例。 它存儲(chǔ)的是源文件中出現(xiàn)的double型數(shù)據(jù)的值。 同樣, 作為常量池中的一種數(shù)據(jù)類型, 它的第一個(gè)字節(jié)也是一個(gè)tag值, 它的tag值為6, 也就是說(shuō), 當(dāng)虛擬機(jī)讀到一個(gè)tag值為6的數(shù)據(jù)項(xiàng)時(shí), 就知道這個(gè)數(shù)據(jù)項(xiàng)是一個(gè)CONSTANT_Double_info, 并且知道它存儲(chǔ)的是double型數(shù)值。 緊挨著tag的下面8個(gè)字節(jié)叫做bytes, 就是double型的數(shù)值。 它的內(nèi)存布局如下:


舉例說(shuō)明, 如果源文件中的一句代碼使用了一個(gè)double型的數(shù)值, 如下所示:
  1. void printDouble(){  
  2.     System.out.println(123456D);  
  3. }  


那么在這個(gè)類的常量池中就會(huì)有一個(gè)CONSTANT_Double_info與之相對(duì)應(yīng), 這個(gè)CONSTANT_Double_info的形式如下:


代碼反編譯結(jié)果為:
[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. Constant pool:  
  2.   
  3. ..............  
  4. ..............  
  5.   
  6.   #21 = Double             123456.0d  
  7.   
  8. ..............  
  9. ..............  
  10.   
  11. {  
  12.   
  13. ..............  
  14. ..............  
  15.   
  16.   void printDouble();  
  17.     flags:  
  18.     Code:  
  19.       stack=3, locals=1, args_size=1  
  20.          0: getstatic     #15                 // Field java/lang/System.out:Ljava/io/PrintStream;  
  21.          3: ldc2_w        #21                 // double 123456.0d  
  22.          6: invokevirtual #23                 // Method java/io/PrintStream.println:(D)V  
  23.          9: return  
  24.       LineNumberTable:  
  25.         line 7: 0  
  26.         line 8: 9  
  27.       LocalVariableTable:  
  28.         Start  Length  Slot  Name   Signature  
  29.                0      10     0  this   Lcom/jg/zhang/TestInt;  
  30. }  


(7) CONSTANT_String_info


在常量池中, 一個(gè)CONSTANT_String_info數(shù)據(jù)項(xiàng), 是CONSTANT_String類型的一個(gè)實(shí)例。 它的作用是存儲(chǔ)文字字符串, 可以把他看做是一個(gè)存在于class文件中的字符串對(duì)象。 同樣, 它的第一個(gè)字節(jié)是tag值, 值為8 , 也就是說(shuō), 虛擬機(jī)訪問(wèn)一個(gè)數(shù)據(jù)項(xiàng)時(shí), 判斷tag值為8 , 就說(shuō)明訪問(wèn)的數(shù)據(jù)項(xiàng)是一個(gè)CONSTANT_String_info 。 緊挨著tag的后兩個(gè)字節(jié)是一個(gè)叫做string_index的常量池引用, 它指向一個(gè)CONSTANT_Utf8_info, 這個(gè)CONSTANT_Utf8_info存放的才是字符串的字面量。 它的內(nèi)存布局如下:



舉例說(shuō)明, 如果源文件中的一句代碼使用了一個(gè)字符串常量, 如下所示:
  1. void printStrng(){  
  2.     System.out.println("abcdef");  
  3. }  

那么在這個(gè)類的常量池中就會(huì)有一個(gè)CONSTANT_String_info與之相對(duì)應(yīng), 反編譯結(jié)果如下:
[plain] view plain copy
在CODE上查看代碼片派生到我的代碼片
  1. Constant pool:  
  2.   
  3. ..............  
  4. ..............  
  5.     
  6.   #21 = String             #22            //  abcdef  
  7.   #22 = Utf8               abcdef  
  8.   
  9. ..............  
  10. ..............  
  11.   
  12. {  
  13.   
  14. ..............  
  15. ..............  
  16.   
  17.   void printStrng();  
  18.     flags:  
  19.     Code:  
  20.       stack=2, locals=1, args_size=1  
  21.          0: getstatic     #15                 // Field java/lang/System.out:Ljava/io/PrintStream;  
  22.          3: ldc           #21                 // String abcdef  
  23.          5: invokevirtual #23                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V  
  24.          8: return  
  25.       LineNumberTable:  
  26.         line 7: 0  
  27.         line 8: 8  
  28.       LocalVariableTable:  
  29.         Start  Length  Slot  Name   Signature  
  30.                0       9     0  this   Lcom/jg/zhang/TestInt;  
  31. }  

其中printString方法中索引為3的字節(jié)碼指令ldc引用常量池中的第21項(xiàng), 第21項(xiàng)是一個(gè)CONSTANT_String_info, 這個(gè)位于第21項(xiàng)的CONSTANT_String_info又引用了常量池的第22項(xiàng), 第22項(xiàng)是一個(gè)CONSTANT_Utf8_info, 這個(gè)CONSTANT_Utf8_info中存儲(chǔ)的字符串是 abcdef 。 引用關(guān)系的內(nèi)存布局如下:




總結(jié)


本文就到此為止。 最后總結(jié)一下, 本文主要講解了常量池中的五中數(shù)據(jù)項(xiàng), 分別為CONSTANT_Integer_info, CONSTANT_Float_info, CONSTANT_Long_info, CONSTANT_Double_info 和CONSTANT_String_info 。 這幾種常量池?cái)?shù)據(jù)項(xiàng)都是直接存儲(chǔ)的常量值,而不是符號(hào)引用。 這里又一次出現(xiàn)了符號(hào)引用的概念, 這個(gè)概念將會(huì)在下一篇博客中詳細(xì)講解, 因?yàn)橄乱黄┛鸵榻B的剩下的四種常量池?cái)?shù)據(jù)項(xiàng), 都是符號(hào)引用, 這四種表示符號(hào)引用的數(shù)據(jù)項(xiàng)又會(huì)直接或間接引用上篇文章中介紹的CONSTANT_NameAndType_info和CONSTANT_Utf8_info, 所以說(shuō)CONSTANT_NameAndType_info是符號(hào)引用的一部分。 

從本文中我們還可以知道。 雖然說(shuō)CONSTANT_String_info是直接存儲(chǔ)值的數(shù)據(jù)項(xiàng), 但是CONSTANT_String_info有點(diǎn)特別, 因?yàn)樗皇侵苯哟鎯?chǔ)字符串, 而是引用了一個(gè)CONSTANT_Utf8_info, 這個(gè)被引用的CONSTANT_Utf8_info中存儲(chǔ)了字符串。 

最后, 列出下一篇博文要介紹的剩下的四種常量池?cái)?shù)據(jù)項(xiàng):
  1. CONSTANT_Class_info
  2. CONSTANT_Fieldref_info
  3. CONSTANT_Methodref_info
  4. CONSTANT_InterfaceMethodref_info



更多關(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)論公約

    類似文章 更多