在 Java 中,泛型在编译后会“被擦除”,这就是著名的 类型擦除(Type Erasure)。下面分层说明“泛型去哪了”。
在 .java 源码阶段,泛型是真实存在的:
List<String> list = new ArrayList<>();
list.add("abc");
String s = list.get(0);
编译器会:
✅ 编译期:泛型用于类型检查
.class 文件):泛型被擦除Java 编译器在生成 .class 文件时:
泛型信息被“擦除”
例如:
List<String>
编译后变成:
List
(在字节码中通常是 Ljava/util/List;)
| 泛型写法 | 编译后 |
|---|---|
T |
Object |
T extends Number |
Number |
List<String> |
List |
Map<String, Integer> |
Map |
✅ 运行期:没有泛型
源码:
String s = list.get(0);
编译后等价于:
String s = (String) list.get(0);
通过 反射 + 特殊结构 可以保留少量泛型信息:
例如:
class Box<T> {}
反射可获取:
Box.class.getTypeParameters();
但 new Box<String>() 中的 String 无法获取
原因很现实:
代价:
List<String> 和 List<Integer>instanceof List<String>new T()如下情况泛型信息会保留(在 Signature 属性 中):
class A<T> {}
void method(List<String> list) {}
反射可以读到,但:
Java 泛型只存在于编译期,编译后被擦除为 Object(或上限类型),并靠强制类型转换保证安全。
如果你愿意,我可以:
Bridge Method 为什么存在你想看哪一个?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。