JDK8中关于lambdas的bug| Java Debug 笔记

简介: 本期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)


场景模拟


代码如下


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 的情况下,怎么保证代码的正常运行呢?


解决办法


从源码入手先~


下面是 OptionalorElseThrow源码


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


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


网络异常,图片无法展示
|


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


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

网络异常,图片无法展示
|


泛型


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


泛型的特点:


  1. 编译擦除


  1. 类型安全


  1. 消除强制类型转换


泛型类


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 推导泛型的类型时出错了 ,手动指定该类型即可解决问题!


  1. 可以通过升级 JDK 的版本来解决这个问题


  1. 如果你想更深入了解这个 lambda ,可以研究下


java.lang.invoke.LambdaMetafactory



目录
相关文章
|
3月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
279 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
4月前
|
安全 Java 微服务
Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
489 1
|
4月前
|
Oracle Java 关系型数据库
新手必看:Java 开发环境搭建之 JDK 与 Maven
本文分享了 Java 学习中 JDK 安装配置与 Maven 使用的入门知识,涵盖 JDK 下载安装、环境变量设置、Maven 安装配置及本地仓库与镜像设置,帮助新手快速搭建 Java 开发环境。
415 0
|
5月前
|
安全 Java API
Java最新技术(JDK 11+) 及以上 Java 最新技术之集合框架实操应用详解
本示例基于Java最新技术(JDK 11+),涵盖集合框架的核心功能,结合Java 8+特性(如Stream API、Lambda表达式)与并发编程最佳实践。内容包括:List操作(初始化、Lambda过滤、Stream处理)、Map操作(流式过滤、ConcurrentHashMap原子操作、并行流)、Set操作(TreeSet排序、CopyOnWriteArraySet并发安全)、Queue/Deque操作(优先队列、双端队列)以及高级聚合操作(集合转换、分组统计、平均值计算)。 [代码下载](https://pan.quark.cn/s/14fcf913bae6)
100 4
|
10月前
|
存储 Java 开发者
【潜意识Java】深入详细理解分析Java中的toString()方法重写完整笔记总结,超级详细。
本文详细介绍了 Java 中 `toString()` 方法的重写技巧及其重要
510 10
【潜意识Java】深入详细理解分析Java中的toString()方法重写完整笔记总结,超级详细。
|
9月前
|
Java API 数据安全/隐私保护
探索Java动态代理的奥秘:JDK vs CGLIB
动态代理是一种在 运行时动态生成代理类的技术,无需手动编写代理类代码。它通过拦截目标方法的调用,实现对核心逻辑的 无侵入式增强(如日志、事务、权限控制等)。
268 0
探索Java动态代理的奥秘:JDK vs CGLIB
|
10月前
|
算法 Java 编译器
深入理解 Java JDK —— 让我们从基础到进阶
JDK(Java Development Kit)是 Java 开发的核心工具包,包含编译、运行和调试 Java 程序所需的所有工具和库。它主要由 JVM(Java 虚拟机)、JRE(Java 运行时环境)和 Java 核心类库组成。JVM 是跨平台运行的基础,负责字节码的加载、执行和内存管理;JRE 提供运行 Java 应用的环境;核心类库则提供了丰富的 API 支持。通过编写、编译和运行一个简单的 Java 程序,可以深入理解 JDK 的工作原理。此外,JDK 还提供了 JIT 编译、垃圾回收优化和并发工具包等高级功能,帮助开发者提高程序性能和稳定性。
1062 10
|
10月前
|
前端开发 JavaScript Java
Java构建工具-maven的复习笔记【适用于复习】
这篇文档由「潜意识Java」创作,主要介绍Maven的相关知识。内容涵盖Maven的基本概念、作用、项目导入步骤、依赖管理(包括依赖配置、代码示例、总结)、依赖传递、依赖范围以及依赖的生命周期等七个方面。作者擅长前端开发,秉持“得之坦然,失之淡然”的座右铭。期待您的点赞、关注和收藏,这将是作者持续创作的动力! [个人主页](https://blog.csdn.net/weixin_73355603?spm=1000.2115.3001.5343)
218 3