是的,六个月过去了这么快,现在到了,Java 14的发布即将到来。 我们一直在跟踪新JDK在过去半年中的进展,您可以在此处找到摘要的所有功能。
但是,如果您想直接进入,可以在此处找到JDK 14二进制文件 。
Java 14 –事实
专家组成立于6月,是迈向下一个Java版本的第一步。 该小组的成员包括Simon Ritter(Azul Systems),Manoj Palat(Eclipse Foundation),Tim Ellison(IBM),Andrew Haley(Red Hat),Volker Simonis(SAP SE),Iris Clark(Oracle),当然还有Brian Goetz (也是Oracle)。
JDK 14为Java编程语言带来了16个新功能。 他们中的一些比其他人更有趣,其中一些更像家政服务。 以下是新功能的摘要:
- instanceof的模式匹配(预览)
- 包装工具(培养箱)
- G1的NUMA感知内存分配
- JFR事件流
- 非易失性映射字节缓冲区
- 有用的NullPointerExceptions
- 记录(预览)
- 开关表达式(标准)
- 弃用Solaris和SPARC端口
- 删除并发标记扫描(CMS)垃圾收集器
- Mac OS上的ZGC
- Windows上的ZGC
- 弃用ParallelScavenge + SerialOld GC组合
- 删除Pack200工具和API
- 文本块(第二预览)
- 外部存储器访问API(孵化器)
让我们更详细地研究每一个。
Java 14的功能
确认以下JEP针对Java 14:
在Project Amber的过程中,正在研究Java的模式匹配。 对于instanceof
运算符,Java 14中的模式匹配已成为(预览)现实,从而使Java编程语言更加简洁和安全。 通过模式匹配,可以精确定义对象的“形式”,然后通过语句和表达式针对它们自己的输入对它们进行测试。
在instanceof
使用模式匹配可能会导致Java应用程序中必要的类型转换大大减少。 在将来的Java版本中,模式匹配可用于其他语言构造,例如开关表达式。
谁会想到我们会再次错过JavaFX? 使用JDK 8,作为JavaFX套件的一部分发布了一个名为javapackager的工具。 但是,随着JDK 11发行版从JavaFX分离JavaFX之后,流行的javapackager不再可用。
打包工具确保可以将Java应用程序打包,使其安装方式与所有其他程序一样。 例如,对于Windows用户,可以通过双击创建*.exe
文件并安装其Java应用程序。 由于该工具被严重遗漏,因此一个名为jpackage的新工具将起起作用 。 用户最终可以基于Java应用程序和运行时映像再次创建自己的Java安装文件。 该工具将这个输入和创建包含所有相关性的Java应用程序的图像(格式: msi
, exe
, pkg
在dmg
, app
在dmg
, deb
和rpm
)。
现在,多核处理器已成为通用标准。 在NUMA内存体系结构中,每个处理器内核都接收少量的本地内存,但其他内核则被授予访问权限。 JEP 345计划为G1垃圾收集器配备可能有利地使用此类体系结构的可能性。 除其他外,这旨在提高功能非常强大的计算机上的性能。
JEP 345专门用于实现对G1垃圾收集器的NUMA支持,仅用于内存管理(内存分配),并且仅在Linux下。 对于其他垃圾收集器还是其他部分(例如任务队列窃取)是否也提供了对NUMA架构的支持。
Java Flight Recorder(JFR)现在是OpenJDK的一部分,因此可以免费获得。 JEP 349创建一个API,通过它可以将Java Flight Recorder收集的数据用于持续监视活动和不活动应用程序。 记录与非流变种相同的事件,开销不到1%。 因此,事件流将与非流变体同时进行。
但是,JEP 349不应允许各个使用者进行同步回调,即使中间存储器中存储的记录数据也不可用。 从技术上讲, jdk.jfr
模块中的软件包jdk.jfr.consumer
可以通过功能扩展以异步访问事件。
JEP 352扩展了MappedByteBuffer
,并具有扩展对非易失性存储器(NVM)的访问的能力。 该内存(也称为持久性内存)用于永久存储数据。 该Java增强建议带来一个新的模块和类到JDK API:该jdk.nio.mapmode
模块可用于创建MappedByteBuffer
(读写或只读),其经由上的NVC文件映射。
通过ManagementFactory
类,可以使用List getPlatformMXBeans(Class)
方法获取BufferPoolMXBean
实例的List getPlatformMXBeans(Class)
。 对此进行了修改,以使其捕获由上述模块映射的所有MappedByteBuffer
实例的某些统计信息。
程序和Java应用程序也不例外,通常由许多方法,对象,函数,注释等组成。 在大量的小零件中,几乎所有地方都可能出现所谓的NullPointerException(NPE)。 JEP 358解决了这个问题。通过分析程序的字节码指令,将来JVM应该能够精确显示哪个变量导致零值。 然后,JVM将在NullPointerException中输出一个null-detail消息 ,该消息出现在常规消息旁边。 上面的示例如下所示:
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field 'i' because 'a' is null.
at Prog.main(Prog.java:5)
因此,用于更复杂示例( abci = 99;
)的消息将如下所示:
Exception in thread "main" java.lang.NullPointerException:
Cannot read field 'c' because 'a.b' is null.
at Prog.main(Prog.java:5)
JEP 358的目的是为作者和开发人员提供重要和有用的信息,以进行故障排除。 新的开发人员将不再那么困惑,不必担心NPE,并且可以提高对该程序的总体了解。
JEP 359将记录作为Java的预览功能。 记录是在Valhalla项目过程中开发的一种新类型。 这些(如枚举 )代表声明class
的受限形式。 记录与经典类的不同之处在于它们不能将其API与它的表示分离。 但是失去的自由度可以通过提高精度来补偿。
在记录提案中,有人说记录是“状态,整个状态,只有状态”。 它由名称,状态描述和正文组成:
record Point(int x, int y) { }
记录仍然是类,即使它们受到限制。 例如,它们可以包含批注或Javadocs,并将其主体声明为静态字段,方法,构造函数或实例方法。 但是,他们不能做的是扩展其他类或声明实例字段( 记录头中声明的状态组件除外)。
对于JEP 325(切换表达式) ,提出了扩展switch语句的建议,以便可以将其用作语句或表达式。 两种形式都应该能够使用“传统”或“简化”变量和控制结构。 该JEP的目的是简化日常编程并结合switch语句为模式匹配( JEP 305 )铺平道路。
该提议最初会更改案例表示法。 自Java 12起,除了明显的箭头(而不是冒号)外,还可以列出几个值进行测试。尤其值得注意的是,不再需要中断。
Gavin Bierman建议使用JEP 354来稍微调整一下功能。 要从switch表达式输出值,应使用yield语句替换value语句。 否则,开关表达式将保持不变,并且现在应该成为下一个Java版本之一的一部分,甚至可能是Java 14的一部分。
Solaris操作系统仍然是Sun Microsystems清单的一部分,并且不再是最新的。 因此,Oracle希望将Solaris / SPARC,Solaris / x64和Linux / SPARC的端口标记为已弃用就不足为奇了。 根据JEP 362 ,下一步是在将来的更新中消除它们。 但是,应该注意的是,旧的Java版本(最高JDK 14)应在旧的系统上运行,包括相应的端口。
整个过程的目标是能够照顾其他功能。 但是,如果有一群热心且感兴趣的开发人员想要维护和管理端口,则以后可能会撤消从JDK移除的操作。
在Java 14中,Thomas Schatzl提出的JEP 363旨在在Java 9( JEP 291 )中将并发标记扫描(CMS)垃圾收集器标记为已弃用之后,将其删除。 根据Schatzl的说法,感兴趣的用户有两年的时间来负责该项目。 到目前为止,情况并非如此,现在正在为Mark Sweep准备最后的仪式。
但是依靠CMS GC的Java较旧版本的用户可以松一口气-目的不是要从JDK的早期版本中删除垃圾收集器。 对于其他垃圾收集器(例如Shenendoah或ZGC)也是如此,尽管这不用说; 这些保留在JDK中,与新的JEP无关。
由ErikÖsterlund创建的JEP 364也处理垃圾收集。 该提案的目标是提供Z垃圾收集器作为macOS用户的选项。 JEP的一部分还包括收集器的功能,可以为系统释放未使用的内存,如JEP 351中所建议。 自Java 13起,此功能已包含在JDK中。
JEP 365实际上是与JEP 364相同的提议,唯一的区别是JEP 365是关于为Windows提供Z垃圾收集器(ZGC)。 ZGC的大多数代码库都是与平台无关的,因此,使其适合Windows仅需进行少量开发即可。 它与较早的Windows版本兼容的限制-Windows 10和Windows Server不应早于版本1803,因为较早的版本不包含内存预留所需的API。
JEP 366也是关于垃圾收集器的,或者在这种情况下是两个“垃圾收集器”的组合:ParallelScavenge和SerialOld。 建议将这两种算法的组合标记为已弃用,因为可能只有很少的开发人员在此构架中使用它们。 最后,这与成本效益因素有关,因为相对于其实际使用情况,要使此组合保持最新状态需要付出相当大的努力。 但是,不应完全删除通过-XX:UseParallelGC
和-XX:-UseParallelOldGC
调用的组合。 但是,在Thomas J. Schatzl的建议下,垃圾收集器Parallel是一个不错的选择。
该Pack200压缩主题,这是用来压缩JAR文件,已被标记为已过时,因为Java的11 JEP 367现在是正式提案删除工具pack200
和unpack200
以及从该Pack200 API java.util.jar
包。 该技术当时是在Java 5中引入的,它是对当时仍然非常有限的带宽(56k调制解调器)和硬盘上存储空间不足的一种反应。 不久前,使用Java 9引入了新的压缩方案。 建议开发人员使用jlink。
JEP 326计划在版本12中已经为编程语言添加了所谓的原始字符串文字。这样的原始字符串文字可以扩展到几行代码,并且不会解释\n
等转义序列或\uXXXX
等Unicode转义序列\uXXXX
。 与传统的字符串文字不同,新的补充原始文字不应被解释,而应以字符串形式生成。 因此,说“原始且未经处理”,它们应该使开发人员更容易以可读的形式表达字符序列,并且没有Java指示符。 这个JEP进行了很多讨论,最终因需要紧急修订而搁浅,因为Brian Goetz将其放在Amber Spec Experts邮件列表上进行辩论。 邀请了专门的Java开发人员提供意见并参与该过程。
在Java 13中, JEP 355作为预览功能被引入,以引入新的文本块类型。 JEP的工作基于为JEP 326和原始字符串文字奠定的基础。 提案中描述的文本块应该根据相应的JEP草案代表多行字符串文字。 它们的格式应遵循统一的规则,并应基于源代码中文本的表示形式,以便开发人员不一定必须诉诸命令来影响文本的布局。 与引入文本块相关的目标之一是使程序员更容易创建多行字符串。 引入类型时,自动格式设置规则将不需要\n
样式转义序列。 特别是,在字符串中包含来自其他编程语言的代码的Java程序应通过新格式更具可读性。
JEP 368现在是第二个预览。 根据反馈,功能中添加了两个新的转义序列,它们可以对换行和空格的处理进行细粒度控制: \<line-terminator>
和\s
。 第一个转义序列可用于强制中断非常长的字符串文字,而无需将其拆分为较小的“子字符串”。
没有\<line-terminator>
的转义序列:
String literal = "Lorem ipsum dolor sit amet, consectetur adipiscing " +
"elit, sed do eiusmod tempor incididunt ut labore " +
"et dolore magna aliqua.";
使用\<line-terminator>
的转义序列:
String text = """
Lorem ipsum dolor sit amet, consectetur adipiscing \
elit, sed do eiusmod tempor incididunt ut labore \
et dolore magna aliqua.\
""";
转义序列\s
可以很容易地描述为单个空格( \u0020
)。 这可以确保在下面的示例中,这些行正好具有6位数字,并且不再存在:
String colors = """
red \s
green\s
blue \s
""";
此转义序列可以在新的文本块中使用,也可以在经典的字符串文字中使用。
有大量访问外部存储器的Java库和应用程序。 突出的示例是Ignite,mapDB,memchaced或Nettys ByteBuf API。 但是,尽管Java API本身可以节省垃圾收集的成本(尤其是在管理大型缓存时),并且可以跨多个进程共享内存,但是它本身并不是提供一种好的方法。 通过访问外部存储器(例如,通过mmap),还可以通过存储器中文件的映射对存储器内容进行序列化和反序列化。
借助JEP 370 ,将在Java 14的JDK中实现合适的Java API,借助Java API,Java应用程序可以安全有效地访问位于Java堆外部的外部内存。 这三个前提很重要:一般有效性,安全性和确定性。
前者意味着单个API应该与不同的外部内存(本机内存,持久性内存等)结合使用。 JVM的安全性是最高的,因此,无论使用哪种内存,API都不能渗透到它。 另外(确定性),内存释放应在源代码中明确说明。
该JEP是在巴拿马计划期间开发的,是使用ByteBuffer,Unsafe或JNI等现有API的明显替代方案。 当然,该实现有助于实现项目的总体准则:对Java本机互操作性的支持。
Java 14发布时间表
与往常一样,Mark Reinhold在jdk-dev邮件列表上共享了计划的发布时间表。 它是这样展现的:
日期 | 事件 |
2019年12月12日 | 开始第一阶段 |
2020年1月16日 | 开始Rampdown第二阶段 |
2020年2月6日 | 首次发布候选 |
2020年2月20日 | 最终发布候选 |
2020年3月17日 | Java 14发行 |
JDK 15功能预览
在这一点上,我们也可以开始得出有关JDK 15可能功能的结论。 具有两个预览功能和一个JDK 14中的孵化器,可以合理地认为我们可能会看到instanceof
模式匹配或文本块已完全增长,或者包装工具可能会从其孵化状态中消失。
如果您喜欢Java,为什么不看看我们的Java 15新闻 ?