您的位置:首页 >Java反射绕过泛型存入String方法
发布于2026-02-26 阅读(0)
扫一扫,手机访问
能。泛型擦除后List的add()方法可通过反射调用,JVM仅校验参数是否为Object类型,不检查泛型约束,添加非Integer元素不会立即报错,而是在后续强转或拆箱时抛ClassCastException。

List 的 add() 方法还能被反射调用吗能。泛型只在编译期起作用,运行时 List 和 List 都是 List,底层 class 是同一个。反射调用 add() 时,JVM 不做泛型参数校验,只检查参数是否符合方法签名的原始类型(即 Object)。
常见错误现象:ClassCastException 不会在 add() 时抛出,而是在后续取值并强转为 Integer 时爆发,比如 list.get(0) + 1 或遍历时自动拆箱。
add() 前,不需要任何额外操作(如修改 AccessibleObject.setAccessible(true),因为 add() 是 public)"hello" 这种 String 完全合法——JVM 只认它是个 ObjectCollections.unmodifiableList() 包装的,反射调用会触发 UnsupportedOperationException,和泛型无关List 添加 String 的最小可行代码核心就是绕过编译器检查,把字符串塞进去。关键不是“怎么绕”,而是“绕完之后怎么不出事”——其实根本不出事,直到你把它当 Integer 用。
List<Integer> list = new ArrayList<>();
list.add(42); // 正常添加整数
// 反射添加字符串
try {
Method add = list.getClass().getMethod("add", Object.class);
add.invoke(list, "oops"); // 成功!list.size() 变成 2
} catch (Exception e) {
e.printStackTrace();
}
此时 list 内部实际是 [42, "oops"]。后续执行 for (Integer x : list) { ... } 会直接在第二次迭代时抛 ClassCastException,因为 "oops" 无法转成 Integer。
get() 返回 Object,但为什么 IDE/编译器不警告因为反射调用 get() 返回的是 Object,你必须自己转型;而泛型的类型信息在运行时已擦除,IDE 和编译器对反射调用完全“失明”。它们只能看到你在写 (Integer) obj,但不知道 obj 实际是什么。
list.get(1) 得到 "oops",若写 Integer x = (Integer) list.get(1),编译通过,运行时报错list.forEach(System.out::println) 能正常打印,因为 println 接受 Object,不触发转型stream().mapToInt(x -> x).sum(),会在 map 阶段就崩,因为 mapToInt 内部隐式调用 intValue()不是技术做不到,而是后果不可控:泛型约束失效后,类型安全边界消失,错误延迟暴露,调试成本陡增。最常被忽略的不是反射本身,而是「集合被多个模块共享」时的隐式污染。
List 被 A 模块反射塞了字符串,B 模块按契约遍历并计算 sum —— B 模块崩溃,但 bug 根源在 A真正难的从来不是“怎么加进去”,而是“怎么让所有人——包括三个月后的你自己——意识到这里已经混进了非 Integer”。
上一篇:美图秀秀滤镜不显示解决方法
下一篇:美图秀秀滤镜加载慢解决方法
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9