java - 为什么在类文件中可以看到泛型类型信息?
问题描述
根据https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html ,
每个无界类型都应Object
由编译器替换。
我有一堂课:
public class Test<E> {
void setE(E e) {
return;
}
}
在 Idea 中反编译后的结果是这样的:
public class Test<E> {
public Test() {
}
void setE(E e) {
}
}
为什么E
不换成Object
?
解决方案
该教程在这里有些误导。它试图说明类型擦除的问题,但它做得不是很优雅。
您生成的类的字节码如下。显然,这些信息不会被丢弃。
Last modified 2 Mar 2020; size 332 bytes
MD5 checksum e3b7faf33fd5666eae578bd516d0f903
Compiled from "Test.java"
public class Test<E extends java.lang.Object> extends java.lang.Object
minor version: 0
major version: 53
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #2 // Test
super_class: #3 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 2
Constant pool:
#1 = Methodref #3.#15 // java/lang/Object."<init>":()V
#2 = Class #16 // Test
#3 = Class #17 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 setE
#9 = Utf8 (Ljava/lang/Object;)V
#10 = Utf8 Signature
#11 = Utf8 (TE;)V
#12 = Utf8 <E:Ljava/lang/Object;>Ljava/lang/Object;
#13 = Utf8 SourceFile
#14 = Utf8 Test.java
#15 = NameAndType #4:#5 // "<init>":()V
#16 = Utf8 Test
#17 = Utf8 java/lang/Object
{
public 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 1: 0
void setE(E);
descriptor: (Ljava/lang/Object;)V
flags: (0x0000)
Code:
stack=0, locals=2, args_size=2
0: return
LineNumberTable:
line 3: 0
Signature: #11 // (TE;)V
}
Signature: #12 // <E:Ljava/lang/Object;>Ljava/lang/Object;
SourceFile: "Test.java"
这些信息不能在字节码中丢弃的原因是想象这个类是库的一部分;另一个项目依赖于它。在第二个项目的编译时,他们的编译器需要能够断言泛型类型参数是否在界限内。如果它被完全扔掉,他们将不得不写
Test test = new Test();
而我,在我的源项目中,可以写
Test<String> test = new Test<>():
推荐阅读
- javascript - 如何使用javascript根据另一个div对齐动态对齐div?
- node.js - 猫鼬模式包含整个数据库对象而不是定义的模式对象
- docker - 如何使用 traefik 在 docker compose 中代理到后端
- javascript - Tabulator.js 停止初始 ajax 数据加载并在第一次过滤后加载数据
- c# - Modifying a JSON file using System.Text.Json
- javascript - 使用 WebGL 在画布上绘图后,HtmlCanvasElement toDataURL 似乎不起作用
- selenium - selenium.JavascriptException:javascript 错误:无法在“文档”上执行“elementFromPoint”:提供的双精度值是非有限的
- r - Create ranges by accumulating values
- postgresql - select all rows where array elements exist
- android - WorkManager PeriodicWorkRequest run twice