泛型列表与异常表现不符:m1()未抛出预期运行时异常
嘿,我来帮你捋清楚这个问题~你之所以觉得应该抛出异常,大概率是混淆了类继承规则和泛型通配符的实际作用——咱们一步步拆解:
首先明确:RuntimeException确实不能继承自身,但你的代码里完全没涉及这个场景,自然不会抛出异常。
1. 先搞懂List<? extends RuntimeException>的含义
这个泛型通配符是上界通配符,它表示:这个List可以是RuntimeException本身的列表,也可以是它任意子类的列表(比如List<IllegalArgumentException>、List<NullPointerException>都能传给m1方法)。你传入的List<RuntimeException>完全符合这个要求,所以编译和运行都不会有问题。
2. 你的m1方法逻辑没有异常触发点
看你的m1实现:
public static void m1(List<? extends RuntimeException> l) { for (RuntimeException a : l) System.out.println(a); }
这里只是遍历列表、打印每个异常对象的字符串表示——你添加到列表里的IllegalArgumentException(它本身就是RuntimeException的子类)和RuntimeException实例,都是合法的元素,遍历打印完全正常,没有任何会抛出运行时异常的操作。
3. 什么时候才会出现你预期的「异常」?
如果你的代码试图在m1方法里往这个列表写入元素,比如:
public static void m1(List<? extends RuntimeException> l) { l.add(new RuntimeException()); // 这里会直接编译报错! }
这时候编译器会阻止你,因为<? extends RuntimeException>只允许读取元素,不允许写入(除了null)——编译器无法确定列表实际的类型是RuntimeException还是它的某个子类,比如如果传入的是List<IllegalArgumentException>,添加RuntimeException就会类型不兼容。但这是编译错误,不是运行时异常。
而你当前的代码既没有编译错误,也没有运行时的错误逻辑,所以自然会正常执行,不会抛出异常。
内容的提问来源于stack exchange,提问作者Joker

