前情回顧
- CONSTANT_Utf8_info
- CONSTANT_NameAndType_info 。
常量池中各數據項類型詳解(續)
(3)CONSTANT_Integer_info
package com.jg.zhang;
public class TestInt {
void printInt(){
System.out.println(65535);
}
}
將上面的類生成的class文件反編譯:
D:\Workspace\AndroidWorkspace\BlogTest\bin>javap -v -c -classpath . com.jg.zhang.TestInt
下面列出反編譯的結果, 由於反編譯結果較長, 我們省略了大部分信息:
..................
..................
Constant pool:
..................
..................
#21 = Integer 65535
..................
..................
{
..................
..................
void printInt();
flags:
Code:
stack=2, locals=1, args_size=1
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #21 // int 65535
5: invokevirtual #22 // Method java/io/PrintStream.println:(I)V
8: return
LineNumberTable:
line 6: 0
line 7: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcom/jg/zhang/TestInt;
}
上面的輸出結果中, 保留了printInt方法的反編譯結果, 並且保留了常量池中的第21項。 首先看printInt方法反編譯結果中的索引爲3 的字節碼指令:
3: ldc #21 // int 65535
這條ldc指令, 引用了常量池中的第21項, 而第21項是一個CONSTANT_Integer_info, 並且這個CONSTANT_Integer_info存儲的整型值爲65535 。
(4)CONSTANT_Float_info
void printFloat(){
System.out.println(1234.5f);
}
那麼在這個類的常量池中就會有一個CONSTANT_Float_info與之相對應, 這個CONSTANT_Float_info的形式如下:
Constant pool:
.............
.............
#29 = Float 1234.5f
............
............
{
............
............
void printFloat();
flags:
Code:
stack=2, locals=1, args_size=1
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #29 // float 1234.5f
5: invokevirtual #30 // Method java/io/PrintStream.println:(F)V
8: return
LineNumberTable:
line 10: 0
line 11: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcom/jg/zhang/TestInt;
}
(5)CONSTANT_Long_info
void printLong(){
System.out.println(123456L);
}
Constant pool:
..............
..............
#21 = Long 123456l
..............
..............
{
..............
..............
void printLong();
flags:
Code:
stack=3, locals=1, args_size=1
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc2_w #21 // long 123456l
6: invokevirtual #23 // Method java/io/PrintStream.println:(J)V
9: return
LineNumberTable:
line 7: 0
line 8: 9
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/jg/zhang/TestInt;
}
(6)CONSTANT_Double_info
void printDouble(){
System.out.println(123456D);
}
Constant pool:
..............
..............
#21 = Double 123456.0d
..............
..............
{
..............
..............
void printDouble();
flags:
Code:
stack=3, locals=1, args_size=1
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc2_w #21 // double 123456.0d
6: invokevirtual #23 // Method java/io/PrintStream.println:(D)V
9: return
LineNumberTable:
line 7: 0
line 8: 9
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/jg/zhang/TestInt;
}
(7) CONSTANT_String_info
void printStrng(){
System.out.println("abcdef");
}
Constant pool:
..............
..............
#21 = String #22 // abcdef
#22 = Utf8 abcdef
..............
..............
{
..............
..............
void printStrng();
flags:
Code:
stack=2, locals=1, args_size=1
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #21 // String abcdef
5: invokevirtual #23 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 7: 0
line 8: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcom/jg/zhang/TestInt;
}
其中printString方法中索引爲3的字節碼指令ldc引用常量池中的第21項, 第21項是一個CONSTANT_String_info, 這個位於第21項的CONSTANT_String_info又引用了常量池的第22項, 第22項是一個CONSTANT_Utf8_info, 這個CONSTANT_Utf8_info中存儲的字符串是 abcdef 。 引用關係的內存佈局如下:
總結
- CONSTANT_Class_info
- CONSTANT_Fieldref_info
- CONSTANT_Methodref_info
- CONSTANT_InterfaceMethodref_info
更多關於深入理解Java的文章, 請關注我的專欄 : http://blog.csdn.net/column/details/zhangjg-java-blog.html
更多關於Java和Android等其他技術的文章, 請關注我的博客: http://blog.csdn.net/zhangjg_blog