当前位置:Java -> LTS JDK 21 特性
新的LTS版本一直是Java世界的重大新闻,JDK 21也不例外。它于6月16日进入Rampdown Phase One,意味着功能集已经冻结。包括新功能、增强功能和最终功能在内的15个JEPs构成了一个广泛的功能集。让我们来深入了解即将推出的LTS版本——也许这个版本将是你未来几年的首选版本!
字符串模板是一个试用语言特性和API,旨在简化运行时计算值的字符串表达。现有的Java机制通过连接文字和表达式产生难以阅读的代码,或者与冗长相关。其他语言利用字符串插值,允许简洁,但会带来潜在的安全风险。
模板表达式有助于实现插值的清晰性,而不引入安全漏洞。
看一下带有模板表达式的代码片段:
String name = "Joan";
String info = STR."My name is \{name}";
assert info.equals("My name is Joan"); // true
该表达式由一个模板处理器STR
、一个点和一个包含嵌入表达式\{name}
的模板组成。嵌入表达式可以是字符串,执行算术操作,调用方法,访问字段,甚至跨越多行。
模板处理器只能使用嵌入表达式中的值,并且只能在运行时执行。此外,如果没有负责安全插值和验证结果的模板处理器,就无法使用模板,这增加了操作的安全性。
序列化集合引入了具有定义的遭遇顺序和统一API的集合,用于访问第一个和最后一个元素,并处理正向和逆向顺序的元素。
三个新接口——序列化集合、集合和映射——将被添加到现有的集合类型层次结构中。这三个接口都有新方法,简化了开发过程:
reversed()
方法,以便以相反的顺序查看集合,对元素进行双向操作,执行所有通常的迭代操作,如forEach()
、stream()
等。addFirst(E)
和addLast(E)
方法,可以将元素移动到适当的位置(如果它已经存在于集合中)。put*(K, V)
方法,其功能类似于序列化集合的add*(E)
方法。未命名模式和变量将通过以下方式改进代码的可读性和可维护性:
两者都以下划线字符_
表示。
未命名模式使开发人员能够省略未使用的记录模式中的组件;例如:
... instanceof Point(int x, _)
case Point(int x, _)
未命名变量替代了未使用的变量名称(例如,在try-with-resources
或try-catch
块中);例如:
int _ = q.remove();
... } catch (NumberFormatException _) { ...
(int x, int _) -> x + x
开始学习Java开发的学生可能会发现一些企业级特性过于复杂。这个新功能旨在让他们有机会编写单类程序,并随着知识的增长逐渐扩展这些程序。对于希望编写简单、简洁的应用程序的有经验的开发人员来说,这也将很有用(即使企业级特性通过定义良好的协议相互交互,但隐藏了内部实现细节)。
例如,基本的HelloWorld程序包含了一些对新手来说难以理解但非必要的特性:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
可以简化为:
class HelloWorld {
void main() {
System.out.println("Hello, World!");
}
}
随着学生学习必要的概念,程序可以随着时间变得更加复杂。但与此同时,并不需要为教育目的引入简化的Java语言方言。
在JDK 21中,当代理动态加载到运行的JVM中时,用户将收到警告。 JEP 451为将来的发行版禁止默认情况下动态加载代理铺平了道路,这符合增强Java完整性的持续过程。
代理是组件,它可以在应用程序运行时改变代码。它们通常被服务性工具(如性能分析器和故障排除工具)使用,但开发人员必须授权其更改应用程序。然而,一些使用代理的库可以绕过这一要求,并静默附加到运行的JVM上,从而增加安全风险。
建议是在命令行上使用-XX:+EnableDynamicAgentLoading
选项,显式允许动态加载。幸运的是,大多数服务性工具不使用动态代理加载,因此不会受到影响。至于库,它们必须在启动时使用-javaagent/-agentlib选项加载代理:鼓励维护者更新其文档,介绍如何在启动时加载代理。
密钥封装机制(KEM)API引入了使用非对称(公钥)加密保护对称密钥的加密技术。 KEM使用公钥属性派生相关的对称密钥而无需填充。
目前,Java没有标准的KEM API。然而,这是一种重要的现代技术,用于防御网络攻击,并且很可能成为下一代标准公钥加密算法的一部分。
这些特性在先前版本中引入,并经过一系列改进和后续修改后,在此LTS版本中取得了最终形式。
记录模式首次在JDK 19中引入,用于解构记录值以改进模式匹配。 JEP 440 完善了该功能,并基于反馈进行了多项增强。最重要的变化是删除了增强的for
语句头中出现记录模式的支持。
switch
的模式匹配switch
表达式和语句的模式匹配是在JDK 17中提出的,并在随后的版本中进行了完善。该功能的目的是增强switch
语句的表达能力、适用性和安全性。借助switch
的模式匹配,开发人员可以针对特定模式测试表达式,从而使复杂的数据查询更加简洁和可靠。 完成的功能包括以下改进:
switch
中允许合格的枚举常量作为case常量虚拟线程通过提供根据具体任务创建数千个轻量级线程的机制来增强Java中的并发编程,这些线程可以像常规平台线程一样进行监视、管理和调试。
虚拟线程已作为预览API包含在JDK 19中。 JEP 444 完善了该功能,并根据反馈进行了一些改进:
ZGC是一种可扩展的低延迟垃圾回收器,无论堆大小如何,都具有始终较低的暂停时间(以微秒计)。然而,当前的非分代ZGC将年轻对象和老对象存储在一起,并且每次操作都必须收集所有对象。由于大多数年轻对象都是早夭的,而老对象则往往存在较长时间,因此收集年轻对象需要的资源更少,且可获得更多内存。因此,分代ZGC将分别维护年轻对象和老对象,并更频繁地收集年轻对象,从而减少GC CPU开销和堆内存占用。
外部函数与内存API使Java应用程序能够安全地与Java运行时之外的代码和数据进行交互。FFM API旨在用更可靠的纯Java开发模型取代Java本机接口。
这是FFM API的第三个预览,具有以下修订:
作用域值使开发人员能够在线程内外部共享不可变数据,从而在并发应用程序中实现更可靠和可管理的数据管理。
与线程本地变量不同,作用域值是不可变的,并且与更小的内存占用和复杂性相关联,因此应优先选择使用。
这一特性在JDK 20中进行了培育,现在已经成为预览API。
向量API提高了在运行时可靠编译为最佳向量指令的向量计算的性能。该特性首次在JDK 16中引入。
这是一个第六个孵化器,除了修复错误之外,还有以下显著的增强功能:
结构化并发可以可靠地协调虚拟线程,并改进了并发代码的可观察性和可维护性。
此功能作为一个孵化API纳入了JDK 19,并在随后的发布中重新孵育。这是一个预览API,其中一个显著的变化是StructuredTaskScope::fork(...)
方法返回[Subtask],而不是之前的Future。对于多个任务被视为独立任务而不是单个工作单元(这是结构化并发的目标),Future更加有用。Future涉及调用get()
方法,该方法会阻塞直到结果可用。而在StructuredTaskScope
的情况下,这是适得其反的,因此现在将使用一个永远不会阻塞的resultNow()
。
支持32位操作的最后一个Windows操作系统(Windows 10)将于2025年10月停止生命周期。同时,Windows 32位x86上的虚拟线程的使用并未带来预期的好处。因此,Windows 32位x86端口变得多余,并将在将来的发布版本中被移除。
早期访问版本已经可用。如果您打算升级到新的LTS版本,可以测试新功能并开始规划迁移策略。
推荐阅读: 我们需要担心ChatGpt吗?
本文链接: LTS JDK 21 特性