Java 11中orElseThrow()编译失败,报错未报告Throwable异常怎么办?
问题原因与解决方法
问题根源
你的代码编译失败的核心原因是泛型类型擦除导致的Optional原始类型问题。
当c.list()返回无泛型的原始List时,调用stream()后得到的流元素类型为Object,findFirst()返回的是原始类型的Optional(而非Optional<Lineup>)。此时orElseThrow方法的签名因类型擦除变为:
Object orElseThrow(Supplier<?> exceptionSupplier) throws Throwable
编译器无法识别lambda中抛出的RuntimeException,而是判定可能抛出受检异常Throwable,因此要求你必须捕获或声明该异常。
另外,你直接对Optional返回值做强制类型转换(Lineup)的写法,也会因泛型擦除导致编译器无法正确推导类型,进一步加剧了问题。
解决方法
有两种简洁的修复方式:
方法一:明确指定List泛型类型
强制将c.list()的返回值转为List<Lineup>,让编译器正确推导流和Optional的类型:
Lineup lineup = ((List<Lineup>) c.list()) .stream() .findFirst() .orElseThrow(() -> new RuntimeException("not found"));
方法二:用map()做类型转换
通过map()方法将Object类型元素转为Lineup,避免直接强制转换,同时让Optional泛型明确:
Lineup lineup = c.list() .stream() .findFirst() .map(Lineup.class::cast) .orElseThrow(() -> new RuntimeException("not found"));
最优方案(若可修改源码)
如果c是你维护的类,建议直接让list()方法返回List<Lineup>(通过泛型定义,比如让类实现YourDao<T>,list()方法声明为public List<T> list(),c的类型为YourDao<Lineup>),从根源上避免类型擦除问题。
内容的提问来源于stack exchange,提问作者sbrattla
相关产品推荐
相关产品推荐

