JDK8中关于lambdas的bug

本期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 运行的时候,会直接抛出该错误,编译不通过

image-20210513090401425

网上搜索一番后,看到有人在说是编译器的原因,说 Eclipse 不会 (真的吗。。)

于是我半信半疑地手动编译试下,结果也不行。。

image-20210513090253668

img

JDK8bug?

后面在 Stack Overflow 上发现这个

Throw RuntimeException inside Stream with Optional.orElseThrow

image-20210513141619907

这个老哥说这个是 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

如下:

image-20210513141645391

于是我看了下本地的 JDK 版本 ,都 271 了… 也不行。

我索性将 JDK 切换成 11 的版本,结果正常编译运行起来了!

image-20210513135534687

那么问题来啦,在不升级 JDK 的情况下,怎么保证代码的正常运行呢?

解决办法

从源码入手先~

下面是 OptionalorElseThrow 源码

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { 
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

可以发现这是一个泛型方法,那么根据错误信息提示,尝试着手动添加上这个泛型异常~

image-20210513144912352

结果程序正常运行啦

image-20210513144944548

这里4ye还找到一个大佬在说这个bug,详情请看
https://zhuanlan.zhihu.com/p/111643471

还有来自 StackOverflow 的解答,

Java 8 generics + exceptions compile time error when using a lambda expression

可以发现这里的做法也是手动添加这个异常信息~

image.png

有兴趣的小伙伴们记得看一下~

完结,撒花✿✿ヽ(°▽°)ノ✿

img

泛型

最后简单复习下泛型的几种写法~ ,别忘了泛型的特点

泛型的特点:

  1. 编译擦除
  2. 类型安全
  3. 消除强制类型转换

泛型类

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 方法

总结:

  1. JDK8 在使用 lambdas 推导泛型的类型时出错了 ,手动指定该类型即可解决问题!
  2. 可以通过升级 JDK 的版本来解决这个问题
  3. 如果你想更深入了解这个 lambda ,可以研究下 java.lang.invoke.LambdaMetafactory

我是4ye,我们下期再见啦,ヾ( ̄▽ ̄)ByeBye

欢迎关注,交个朋友呀!! ( •̀ ω •́ )y

作者简介 :Java4ye ,很高兴认识你!!😝

公众号: Java4ye 博主滴个人公众号~ ,嘿嘿 喜欢就支持下啦 😋

让我们开始这一场意外的相遇吧!~

欢迎留言!谢谢支持!ヾ(≧▽≦*)o

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: jdk-8u291-windows-x64 是 Java Development Kit (JDK) 的一个版本,用于在 Windows 64 位操作系统上进行Java开发。 JDK是Java开发的核心工具包,提供了编译、运行和调试Java代码所需的全部工具和资源。而jdk-8u291-windows-x64是该工具包的一个特定版本,具体版本号是8u291,适用于Windows 64位操作系统。 该版本的JDK-8引入了许多新特性和改进。其,最显著的是Lambda表达式、方法引用和函数式接口,它们使得开发者能够更简洁、更灵活地编写Java代码。此外,JDK-8还增强了Java虚拟机(JVM)的性能、安全性和可用性。 对于Windows 64位操作系统的用户来说,jdk-8u291-windows-x64版本具有更好的兼容性和性能优化。它能够更有效地利用64位系统的硬件资源,提供更高的执行速度和更大的内存容量。 要使用jdk-8u291-windows-x64,首先需要从Oracle官方网站下载安装程序,并按照指示进行安装。安装完成后,开发人员就可以使用JDK提供的工具和库来编写、编译和运行Java应用程序。 综上所述,jdk-8u291-windows-x64 是 Java开发工具包的一个版本,适用于Windows 64位操作系统,它提供了Java编程所需的全部工具和资源,支持最新的Java特性和改进,并为64位系统提供更好的兼容性和性能优化。 ### 回答2: jdk-8u291-windows-x64 是Java Development Kit(JDK)的一个版本,适用于64位Windows操作系统。 JDK是一个开发工具包,用于开发、编译和运行Java程序。它提供了一系列的工具和库,包括编译器、调试器、运行时环境等,可以帮助开发人员创建Java应用程序、Applet和服务。 版本号的"8u291"表示该版本是JDK 8的第291个更新版本。更新版本通常包含了修复了之前版本的漏洞和错误,并且提供了新的功能或改进。 "windows-x64"表示该版本适用于64位的Windows操作系统。64位操作系统可以更有效地利用计算机的内存和处理能力,提供更好的性能和扩展性。 安装jdk-8u291-windows-x64,可以让开发人员在64位Windows系统上进行Java程序的开发和运行。这样,他们可以利用JDK提供的丰富工具和库,编写高效、安全的Java应用程序,并在64位系统上获得更好的性能和体验。 总之,jdk-8u291-windows-x64是适用于64位Windows操作系统的Java开发工具包,可以支持开发人员进行Java程序的开发和运行。通过更新版本的安装,可以获得修复的漏洞和错误,以及新功能和改进的体验。 ### 回答3: jdk-8u291-windows-x64是Java Development Kit(JDK)的一个版本。JDK是Java语言开发的核心工具包,其包括了编译器、调试器、运行环境等必要的工具和库。 "jdk-8u291"指的是Java Development Kit的第8个版本,更新编号为291。这表示该版本在之前版本的基础上进行了291次的更新和改进。这些更新可能包括了修复了已知的Bug、增加了新的特性和功能、改进了性能等。 "windows-x64"表示这个版本是为Windows操作系统的64位版本而设计的。64位意味着该版本适用于具有64位处理器的计算机。与32位版本相比,64位版本能够更好地利用计算机的内存和处理能力,从而提供更高的性能和更大的扩展性。 使用该版本的JDK可以让开发者在Windows 64位操作系统上进行Java应用程序的开发和调试工作。开发者可以使用其的编译器将Java源代码编译为Java字节码,然后运行在Java虚拟机(JVM)上。此外,还可以使用其的调试器进行代码的调试和检查。通过使用JDK,开发者能够使用Java语言的各种特性和库,实现各种类型的应用程序,包括桌面应用程序、Web应用程序、移动应用程序等。 总之,jdk-8u291-windows-x64是Java开发工具包的一个版本,适用于Windows 64位操作系统,提供了编译器、调试器、运行环境等工具和库,方便开发者进行Java应用程序的开发和调试工作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值