场景模拟
代码如下
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
不会 (真的吗。。)
于是我半信半疑地手动编译试下,结果也不行。。
JDK8bug?
后面在 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,详情请看zhuanlan.zhihu.com/p/111643471
还有来自 StackOverflow
的解答,
Java 8 generics + exceptions compile time error when using a lambda expression
可以发现这里的做法也是手动添加这个异常信息~
有兴趣的小伙伴们记得看一下~
完结,撒花✿✿ヽ(°▽°)ノ✿
泛型
最后简单复习下泛型的几种写法~ ,别忘了泛型的特点
泛型的特点:
- 编译擦除
- 类型安全
- 消除强制类型转换
泛型类
class Fruit<T> {}
泛型接口
interface IAnimal<T>{}
泛型变量
T a;
泛型方法
T getAnimal();
通配符
List<?>
泛型上下限原则:PECS(Producer Extends Consumer Super)
泛型上限
? 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