本文详解如何在仅修改指定代码段的前提下,使 ArrayList 成功存储并返回一个 String,从而让 equals("Hello World") 返回 true,输出 "Ok"——核心在于利用 Java 泛型的类型擦除与原始类型调用。
本文详解如何在仅修改指定代码段的前提下,使 `arraylist
在 Java 中,泛型是编译期特性,运行时会发生类型擦除:ArrayList
题目要求在以下固定结构中,仅修改 // Change starts here 与 // Change ends here 之间的代码,使 intList.get(0).equals("Hello World") 为 true:
static void insertEvil() {
var intList = new ArrayList<integer>();
// Change starts here
intList.add(42); // ← 必须删掉或替换此行
// Change ends here
if (intList.get(0).equals("Hello World")) {
System.out.println("Ok");
} else {
System.out.println("Failure");
}
}</integer>
⚠️ 注意:直接写 intList.add("Hello World") 会编译失败(类型不匹配);而 ((ArrayList)intList).add("Hello World") 虽能插入字符串,但后续 intList.get(0) 会触发隐式强制转换为 Integer,导致 ClassCastException 运行时异常——因为 get() 方法签名在编译后为 Object get(int),但调用处按 Integer 接收,JVM 尝试将 String 强转 Integer,必然失败。
✅ 正确解法的关键在于:让 intList.get(0) 的调用上下文脱离 ArrayList
// Change starts here
helper(intList);
}
static void helper(ArrayList intList) {
intList.add("Hello World");
// Change ends here
完整整合后,代码逻辑变为:
static void insertEvil() {
var intList = new ArrayList<integer>();
// Change starts here
helper(intList);
}
static void helper(ArrayList intList) {
intList.add("Hello World");
// Change ends here
if (intList.get(0).equals("Hello World")) {
System.out.println("Ok"); // ✅ 执行此处
} else {
System.out.println("Failure");
}
}</integer>
? 原理解析:
- helper(intList) 将 ArrayList
以原始类型传参,形参 ArrayList intList 不含泛型信息; - 在 helper 方法体内,intList.add("Hello World") 直接向底层 Object[] 插入 String;
- 同一作用域中 intList.get(0) 返回 Object(即 "Hello World"),equals("Hello World") 自然返回 true;
- 整个过程规避了 ArrayList
对 get() 返回值的隐式强转,也无需反射或字节码操作。
? 总结:本题并非考察常规编码实践,而是深入理解 Java 泛型本质——类型安全由编译器保障,而非 JVM;擦除后一切皆 Object;原始类型调用是突破泛型边界的安全“后门”。在真实项目中应严格避免此类写法,但掌握它对理解泛型、调试类型异常及阅读遗留代码极具价值。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











