Java中Function<? extends Throwable>无法传参调用apply()方法如何解决
问题根因
你遇到的编译报错是Java泛型通配符的固有约束导致的:
你声明的Function<? extends Throwable, Integer>使用了上界通配符? extends Throwable,表示这个Function的入参是「某一个未知的Throwable子类」,但编译器无法确定这个子类的具体类型。为了避免类型不匹配的风险,编译器会直接禁止你向apply方法传入任何非null的对象——哪怕你传的是IllegalStateException,也没法保证和那个未知的子类匹配,所以直接报错。
这个规则符合Java泛型的PECS原则:生产者(只读取泛型内容的场景)用extends,消费者(需要写入/传入泛型内容的场景,比如给Function传参)用super。
解决方案
根据你的业务场景,可以选以下任意一种方案:
场景1:handler固定处理特定类型异常
如果你的handler就是用来处理IllegalStateException的,直接把泛型写死即可:
Function<IllegalStateException, Integer> handler = (IllegalStateException e) -> { return 0; }; // 调用正常 int result = handler.apply(new IllegalStateException("test"));
场景2:handler需要支持接收所有类型的Throwable
如果要让handler能处理任意异常,直接把入参泛型声明为Throwable即可,内部可以根据异常类型做分支逻辑:
Function<Throwable, Integer> handler = (Throwable e) -> { if (e instanceof IllegalStateException) { return 0; } else if (e instanceof NullPointerException) { return 1; } return 2; }; // 可传入任意Throwable子类实例 int result1 = handler.apply(new IllegalStateException("test")); int result2 = handler.apply(new NullPointerException("test"));
场景3:需要灵活赋值不同的异常处理器
如果需要支持把不同类型的异常处理器赋值给handler变量,同时还要能正常传参,可以改用下界通配符:
// ? super Throwable 表示入参可以是Throwable及其所有父类,所有Throwable子类都能正常传入 Function<? super Throwable, Integer> handler = (Throwable e) -> 0; int result = handler.apply(new IllegalStateException("test"));
如果需要做多异常类型的分发处理,更优雅的实现是用Map存储类型和处理器的映射:
Map<Class<? extends Throwable>, Function<Throwable, Integer>> handlerMap = new HashMap<>(); // 注册不同异常的处理器 handlerMap.put(IllegalStateException.class, e -> 0); handlerMap.put(NullPointerException.class, e -> 1); // 调用时动态匹配处理器 Throwable e = new IllegalStateException("test"); int result = handlerMap.get(e.getClass()).apply(e);
内容的提问来源于stack exchange,提问作者drew
相关产品推荐
相关产品推荐

