Java字节码中的泛型的符号引用有什么作用?
有一段简单的程序如下:
import java.util.HashMap;
public class Test {
private static HashMap<Integer, Object> m = new HashMap<>();
}
使用javap -verbose Test.class
输出的字节码为:
public class com.test.Test
minor version: 0
major version: 55
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #5 // com/test/Test
super_class: #6 // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 1
Constant pool:
#1 = Methodref #6.#21 // java/lang/Object."<init>":()V
#2 = Class #22 // java/util/HashMap
#3 = Methodref #2.#21 // java/util/HashMap."<init>":()V
#4 = Fieldref #5.#23 // com/test/Test.m:Ljava/util/HashMap;
#5 = Class #24 // com/test/Test
#6 = Class #25 // java/lang/Object
#7 = Utf8 m
#8 = Utf8 Ljava/util/HashMap;
#9 = Utf8 Signature
#10 = Utf8 Ljava/util/HashMap<Ljava/lang/Integer;Ljava/lang/Object;>;
#11 = Utf8 <init>
#12 = Utf8 ()V
#13 = Utf8 Code
#14 = Utf8 LineNumberTable
#15 = Utf8 LocalVariableTable
#16 = Utf8 this
#17 = Utf8 Lcom/test/Test;
#18 = Utf8 <clinit>
#19 = Utf8 SourceFile
#20 = Utf8 Test.java
#21 = NameAndType #11:#12 // "<init>":()V
#22 = Utf8 java/util/HashMap
#23 = NameAndType #7:#8 // m:Ljava/util/HashMap;
#24 = Utf8 com/test/Test
#25 = Utf8 java/lang/Object
{
public com.test.Test();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 5: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/test/Test;
static {};
descriptor: ()V
flags: (0x0008) ACC_STATIC
Code:
stack=2, locals=0, args_size=0
0: new #2 // class java/util/HashMap
3: dup
4: invokespecial #3 // Method java/util/HashMap."<init>":()V
7: putstatic #4 // Field m:Ljava/util/HashMap;
10: return
LineNumberTable:
line 7: 0
}
可以注意到在常量池中有一个符号引用:#10 = Utf8 Ljava/util/HashMap<Ljava/lang/Integer;Ljava/lang/Object;>;
这里看上去似乎是一个包含了泛型信息的符号引用,但是整个字节码中并没有引用这个量,请问这个常量的作用是什么呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过
java.lang.reflect.Field#getGenericType
可以获得成员变量的泛型信息,这个引用大概就是为实现这个功能添加的。关于擦除,应该是针对泛型类本身而言的,运行时通过HashMap实例本身无法获取它的泛型参数信息。
可能反射的时候用得到吧,虽然我利用反射取不到泛型参数。