JDK各个版本特性查看地址:https://openjdk.org/projects/jdk/17/(修改后面数字即可,目前最新的是23)
JDK 22 于 2024 年 3 月 19 日全面发布。
一,开发计划
2023/12/07 | Rampdown Phase One (fork from main line) 第一阶段(从主线分叉) | |
2024/01/18 | Rampdown Phase Two 第二阶段 | |
2024/02/08 | Initial Release Candidate初始候选版本 | |
2024/02/22 | Final Release Candidate 最终候选版本 | |
2024/03/19 | General Availability 通用可用性 |
二,新特性
423 Region Pinning for G1(G1的区域固定) |
447 Statements before super(...) |
454 Foreign Function & Memory API(外部函数和内存 API) |
456 Unnamed Variables & Patterns(未命名变量和模式) |
457 Class-File API(类文件 API) |
458 Launch Multi-File Source-Code Programs(启动多文件源代码程序) |
459 String Templates(字符串模板) |
460 Vector API |
461 Stream Gatherers(流收集器) |
462 Structured Concurrency(结构化并发) |
463 Implicitly Declared Classes and Instance Main Methods(隐式声明的类和实例主要方法) |
464 Scoped Values |
三,分析
423: Region Pinning for G1(G1的区域固定)
概括:通过在 G1 中实现区域固定来减少延迟,以便在 Java 本机接口 (JNI) 关键区域期间无需禁用垃圾收集。
目标是:不会因 JNI 关键区域而导致线程停顿。Java 线程将永远不会等待 G1 GC 操作完成。
当 Java 线程位于关键区域时,JVM 必须注意不要在垃圾收集期间移动关联的关键对象。它可以通过将这些对象固定到它们的位置来实现这一点,本质上是在 GC 移动其他对象时将它们锁定在适当的位置。或者,只要线程位于关键区域,它就可以简单地禁用 GC。
默认 GC G1 采用后一种方法,在每个关键区域禁用 GC。这对延迟有显着影响:如果 Java 线程触发 GC,那么它必须等待,直到关键区域中没有其他线程。影响的严重程度取决于关键区域的频率和持续时间。在最糟糕的情况下,用户报告关键部分会阻塞整个应用程序几分钟,由于线程匮乏而导致不必要的内存不足情况,甚至虚拟机过早关闭。由于这些问题,一些 Java 库和框架的维护者选择默认不使用关键区域(例如 JavaCPP),甚至根本不使用关键区域(例如 Netty),尽管这样做会对吞吐量产生不利影响。
447: Statements before super(...)
概括:在 Java 编程语言的构造函数中,允许不引用正在创建的实例的语句出现在显式构造函数调用之前。
目标是:为开发人员提供了更大的自由来表达构造函数的行为,从而可以更自然地放置目前必须纳入辅助静态方法、辅助中间构造函数或构造函数参数中的逻辑。
简单的说是,在子类继承父类的情况下,子类构造方法里,可以在super()前调用方法做参数的预校验等。
“我们需要超越自 Java 1.0 以来强制执行的简单语法要求,即“ super(..)
或 this(..)
必须是第一个语句””
454: Foreign Function & Memory API(外部函数和内存 API)
概括:引入一个FFM API,Java 程序可以通过该 API 与 Java 运行时之外的代码和数据进行互操作。通过有效地调用外部函数(即 JVM 外部的代码),并安全地访问外部内存(即不受 JVM 管理的内存),API 使 Java 程序能够调用本机库并处理本机数据,而不会出现JNI的脆弱性和危险。
简单的说是,新引入FFM(Foreign Function & Memory) API去替换旧的JNI,去操作堆外内存。
456: Unnamed Variables & Patterns(未命名变量和模式)
概括:使用未命名变量和未命名模式增强 Java 编程语言,当需要变量声明或嵌套模式但从未使用时可以使用它们。两者都由下划线字符 _
表示。
目标是:捕获开发人员的意图,即给定的绑定或 lambda 参数未使用,并强制执行该属性,以便澄清程序并减少出错的机会。允许多个模式出现在单个 case
标签中,前提是它们都没有声明任何模式变量。
JDK 22之前
static int count(Iterable<Order> orders) { int total = 0; for (Order order : orders) // order is unused total++; return total; }
JDK 22, 用_来表示未命名的变量
static int count(Iterable<Order> orders) { int total = 0; for (Order _ : orders) // Unnamed variable total++; return total; }
457: Class-File API(类文件 API)
概括:提供用于解析、生成和转换 Java 类文件的标准 API。 目前还是预览版本。
目标:提供用于处理跟踪 Java 虚拟机规范定义的 class
文件格式的类文件的 API。使JDK组件能够迁移到标准API,并最终删除第三方ASM库的JDK内部副本。
简单的说是,要替换掉2002年开始的ASM库。
“自从 ASM 创建以来,Java 语言已经有了很大的改进,因此 2002 年最好的 API 习惯在二十年后可能不再理想。”
458: Launch Multi-File Source-Code Programs(启动多文件源代码程序)
概括:增强 java
应用程序启动器,使其能够运行作为多个Java源代码文件提供的程序
459: String Templates(字符串模板)
概括:使用字符串模板增强 Java 编程语言。字符串模板通过将文字文本与嵌入式表达式和模板处理器耦合来生成专门的结果,从而补充了 Java 现有的字符串文字和文本块。
目标是:通过轻松表达包含运行时计算值的字符串,简化 Java 程序的编写。增强混合文本和表达式的表达式的可读性,无论文本适合单个源行(如字符串文字)还是跨越多个源行(如文本块)。简化接受非 Java 语言(例如 SQL、XML 和 JSON)编写的字符串的 API 的使用。
示例
String name = "Joan Smith"; String phone = "555-123-4567"; String address = "1 Maple Drive, Anytown"; String json = """ { "name": "%s", "phone": "%s", "address": "%s" } """.formatted(name, phone, address); JSONObject doc = JSON.parse(json);
460: Vector API
概括:引入 API 来表达向量计算,在运行时可靠地编译为支持的 CPU 架构上的最佳向量指令,从而实现优于同等标量计算的性能。
目标是:清晰简洁的 API — API 应能够清晰简洁地表达各种向量计算,这些向量计算由循环内组成的向量运算序列组成,并可能包含控制流。应该可以表达关于向量大小或每个向量的通道数的通用计算,从而使此类计算能够跨支持不同向量大小的硬件移植。与平台无关——API 应该与 CPU 架构无关,从而能够在支持向量指令的多个架构上实现。
简单的说,一股GPT味儿,这是Java向AI底层计算迈进的信号吧,不知道开发者买不买账?
461: Stream Gatherers(流收集器)
概括:增强 Stream API 以支持自定义中间操作。这将允许流管道以现有内置中间操作不易实现的方式转换数据。
目标:尽可能允许自定义中间操作来操作无限大小的流。
462: Structured Concurrency(结构化并发)
概括:通过引入结构化并发 API 来简化并发编程。结构化并发将在不同线程中运行的相关任务组视为单个工作单元,从而简化错误处理和取消、提高可靠性并增强可观察性。
目标是:推广一种并发编程风格,可以消除因取消和关闭而产生的常见风险,例如线程泄漏和取消延迟。提高并发代码的可观察性。
463: Implicitly Declared Classes and Instance Main Methods(隐式声明的类和实例主要方法)
概括:学生无需使用单独的语言方言,而是可以为单类程序编写简化的声明,然后随着技能的增长无缝扩展他们的程序以使用更高级的功能。
目标是:为 Java 编程提供一个平稳的入门通道,以便教师可以循序渐进地介绍概念。帮助学生以简洁的方式编写基本程序,并随着他们的技能增长而优雅地扩展他们的代码。不要引入单独的初学者工具链;学生程序应该使用与编译和运行任何 Java 程序相同的工具来编译和运行。
简单的说,就是降低学习Java的难度,不管怎样,先骗入门再说!
以后hello world就是下面这样写了
464: Scoped Values
概括:引入作用域值,这使得能够与同一线程中的子帧以及子线程管理不可变数据的共享。作用域值比线程局部变量更容易推理,并且空间和时间成本更低,特别是与虚拟线程和结构化并发结合使用时。
目标是:易于使用——应该很容易推理数据流。可理解性——共享数据的生命周期从代码的语法结构中是可见的。鲁棒性——调用者共享的数据只能由合法的被调用者检索。性能——数据可以在大量线程之间有效地共享。
简单的说,就是可以共享变量了。
JDK23马上要来了, 你升级JDK8了吗?