本期4ye又带来一个奇怪的Bug啦,是关于 jdk8 中 lambdas 推导泛型失败而导致的编译期错误,下面让我们一起来看看叭
Error:(24, 29) java: 未报告的异常错误java.lang.Throwable; 必须对其进行捕获或声明以便抛出
下面让我们一起来看看叭
import java.util.Optional;
public class B {
public static void main(String[] args) {
String s=null;
Optional.ofNullable(s).orElseThrow(() -> {
throw new RuntimeException("");
});
}
}
用 IDEA
运行的时候,会直接抛出该错误,编译不通过!
网上搜索一番后,看到有人在说是编译器的原因,说 Eclipse
不会 (真的吗。。)
于是我半信半疑地手动编译试下,结果也不行。。
后面在 Stack Overflow
上发现这个
Throw RuntimeException inside Stream with Optional.orElseThrow
这个老哥说这个是 JDK
的 bug ,小伙伴们可以点击下面的连接去看看
This is a compiler bug JDK-8047338 which prevent correct generic exception type inference. It was partially resolved in
1.8.0_92
release
如下:
于是我看了下本地的 JDK
版本 ,都 271 了… 也不行。
我索性将 JDK
切换成 11 的版本,结果正常编译运行起来了!
那么问题来啦,在不升级 JDK
的情况下,怎么保证代码的正常运行呢?
从源码入手先~
下面是 Optional
的 orElseThrow
源码
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
可以发现这是一个泛型方法,那么根据错误信息提示,尝试着手动添加上这个泛型异常~
结果程序正常运行啦
这里4ye还找到一个大佬在说这个bug,详情请看
https://zhuanlan.zhihu.com/p/111643471
还有来自 StackOverflow
的解答,
Java 8 generics + exceptions compile time error when using a lambda expression
可以发现这里的做法也是手动添加这个异常信息~
有兴趣的小伙伴们记得看一下~
完结,撒花✿✿ヽ(°▽°)ノ✿
最后简单复习下泛型的几种写法~ ,别忘了泛型的特点
泛型的特点:
class Fruit
interface IAnimal
T a;
T getAnimal();
List>
? extend T
属于 Producer Extends
,可以 获取值 ,但是不能修改值 。
如: List extend T> 就表明了只能调用 get
方法,不能使用 add
方法
? super T
属于 Consumer Super
,可以 修改值 ,但是不能获取值 。
如: List super T> 就表明了只能调用 add
方法,不能使用 get
方法
JDK8
在使用 lambdas
推导泛型的类型时出错了 ,手动指定该类型即可解决问题!JDK
的版本来解决这个问题lambda
,可以研究下 java.lang.invoke.LambdaMetafactory
我是4ye,我们下期再见啦,ヾ( ̄▽ ̄)ByeBye
作者简介 :Java4ye ,很高兴认识你!!
公众号: Java4ye 博主滴个人公众号~ ,嘿嘿 喜欢就支持下啦
让我们开始这一场意外的相遇吧!~
欢迎留言!谢谢支持!ヾ(≧▽≦*)o