Java 12 有什么新功能2025年3月17日 | 阅读 12 分钟 最近的长期支持(LTS)版本是 Java 12,这是自 2019 年 3 月 19 日发布的 Java 11 以来的第一个“临时”版本。在 Java 的 LTS 版本 11 之后,Java 12 发布了。JDK 12 采用 6 个月的发布周期。2019 年 3 月 19 日,Java 12-一个非 LTS 版本,没有长期支持-可用。与早期版本相比,Java 12 的修改相当微小。语言本身自 Java 7 以来首次没有改变。 Java 12 是 Java 12 SE 平台的一个开源参考实现的名称。 Oracle 提供符合 GPL 的生产就绪二进制文件,其他供应商的二进制文件将很快提供。 Java JDK 12 中没有很多新的 API 功能。JDK 12 的主要进步涉及 Java/JVM 内部。JEP,一项新功能,包含在 JDK 12 中。 根据常规开发者工作的意义,我们对修改进行了排序。我们将首先讨论类库的改进。之后包括性能增强、实验性功能和预览功能,以及您作为开发者可能不会注意到的微小变化。 此外,我们将讨论 Java 12 中的新功能,并检查它为程序员提供了什么。 Java 12 的特性Java 12 的重要特性包括:
1) JVM 更改1. JEP 189 - 低暂停时间的垃圾收集器:Shenandoah(实验性) Shenandoah 垃圾收集器由 RedHat 启动,旨在缩短 GC 暂停时间。计划是在 Java 线程活动时并行运行 GC。无论堆大小如何,它都致力于实现可预测且一致的短暂停顿。因此,无论堆大小是 15 MB 还是 15 GB,都不重要。它是 Java 12 中的一个 beta 功能。 一种名为 Shenandoah 的实验性垃圾收集(GC)机制目前不包含在标准的 Java 12 版本中。 通过在 Java 线程活动时并行执行其疏散工作,可以减少 GC 的停止时间。这意味着无论堆大小如何,使用 Shenandoah 的暂停时间都应该是恒定的。一个 200 GB 的堆垃圾应该具有与 2 GB 堆相似的低暂停行为。 从版本 15 开始,Shenandoah 将被集成到主要的 JDK 构建中。 2. JEP 346:快速从 G1 返回已提交的未使用内存 根据 Java 12,当应用程序不使用时,G1 将检查 Java 堆内存并将其返回给操作系统。这是一种预防性措施,用于保存和利用可用内存。 3. JEP 344 中的 G1 可中断的混合集合 如果 G1 混合集合可能超出指定的暂停阈值,它现在将变得可中断,这将提高 G1 的效率。为此,混合集合集被分为必需和可选类别。为了满足暂停时间目标,G1 收集器可以优先收集必需的集合。 4. JEP 230 和 344 Microbenchmark Suite,JEP 230 功能,现在 JDK 源代码中包含了一套最小的微基准测试。这使得开发人员可以轻松地构建新的微基准测试并运行他们已有的测试。JEP 344,一个 AArch64 端口,而不是两个,保留了 32 位 ARM 和 64 位 aarch64 端口,同时移除了所有与 arm64 端口相关的源代码。因此,开发人员可以专注于创建一个单一的 64 位 ARM 实现。 5. JEP 341 的默认 CDS 存档 这改进了 JDK 构建过程,使其能够使用默认类列表在 64 位平台上创建类数据共享(CDS)存档。目标是缩短启动时间。自 Java 12 起,CDS 默认启用。要禁用 CDS 执行程序,请执行以下操作: 2) 新的 String 和 File 方法在 Java 11 的 Files 和一些新的 String 方法被引入之后。对于 Java 12,JDK 开发人员再次增强了这两个类,增加了 readString() 和 writeString() 功能。 1. indent() 以前,我们必须创建一个小型辅助方法,在该方法前面添加所需数量的空格来缩进字符串。如果需要处理多行,该过程会变得更加复杂。 Java 12 中集成了一个名为 String.indent() 的方法。下面是如何将多行字符串缩进四个空格的示例: 2. transform() 新的 String.transform() 方法使用任何函数转换 String 并返回该函数的结果。这里有一些例子: 从 String.transform() 的源代码可以看出,这并不复杂。一旦方法引用被转换为函数,字符串就会被传递给方法的 apply() 方法。 那么,为什么不直接写成这样,而不是使用 transform() 呢? 与后一种表示法在编译时固定转换不同,String.transform() 允许在运行时动态确定要应用的函数。 3. mismatch() 使用 Files.mismatch() 方法比较两个文件的内容。 如果两个文件匹配,则返回 -1。如果不匹配,则返回第一个字节不匹配的位置。如果其中一个文件在找到差异之前结束,则返回该文件的长度。 (JDK 增强提案中没有包含新的 String 和 Files 方法的定义。)
如果您的需求要求这样做,您可能希望在用两个收集器而不是一个收集器终止流时组合两个收集器的结果。 为了避免被指责有“代码异味”,下面的示例源代码旨在找到流中最大和最小数字之间的差值: 除了一个异常,程序可以构建但会在执行期间崩溃: 从异常文本中我们了解到,我们只能终止流一次。 那么,我们如何完成这项任务呢? 另一种方法是创建一个自定义收集器,该收集器将最小和最大值存储在一个 2 元素的 int 数组中: 这种策略可读性不高,而且相当混乱。 使用 Java 12 引入的“Teeing Collector”,我们可以更快地完成它。我们可以定义两个下游收集器(用于合并两个下游收集器输出的收集器)和一个合并函数: 可读性和优雅性都大大提高,不是吗? 在这种情况下,“Teeing Collector”是什么意思? 由于收集器的图形表示类似于……“T”,因此该名称源自字母“T”的英文发音。 ![]() (Teeing Collector JDK 升级也没有相关的提案。)
以下改进确保我们的 Java 应用程序启动更快,垃圾收集器延迟更低,并且内存占用更少。 默认 CDS 存档 以前,您需要为每个 Java 安装运行一次 java -Xshare:dump 来创建 classes.jsa 共享存档文件。 随着 JDK 增强提案 341 的实施,所有 64 位 JDK 端口都提供了此文件,消除了 Java 应用程序需要运行 java -Xshare:dump 的要求,而是默认使用默认 CDS 存档。 G1 的可中断混合集合 G1 垃圾收集器的目标之一是遵守为它无法与程序并行执行的清理活动设定的最大暂停时间,即不让应用程序停止超过允许的时间。 使用 -XX:MaxGCPauseMillis 参数,您可以为 G1 设置此时间。如果移除该参数,最大允许暂停时间为 200 ms。 为了选择要在此“停止世界”阶段清理的堆区域集,G1 使用一种启发式方法(称为“集合集”)。 启发式方法可能会确定一个过大的集合集,从而导致应用程序中断的时间超过计划的时间,尤其是在“混合集合”(即清理年轻代和老年代区域时)的情况下。 如果最大暂停时间持续被超出,JDK 增强提案 344 会优化混合集合,将集合集分为强制部分和可选部分。直到达到最大暂停时间,可选部分才会分小增量完成,而强制部分则不间断地执行。 该算法试图在此期间修改启发式方法,以便快速选择可以在指定暂停时间内处理的集合集。 快速从 G1 返回未使用的已提交内存 在只为实际使用的内存付费的情况下,垃圾收集器应尽快将未使用的内存返回给操作系统。 G1 垃圾收集器可以返回内存,但仅在收集垃圾时。如果堆分配或当前对象分配速率没有启动垃圾收集周期,则不会返回任何内存。 假设我们有一个程序,除了每天运行一次内存密集型批处理过程外,大部分时间都处于非活动状态。因此,批处理完成后,不需要垃圾收集周期,而我们却要为包含未使用对象的 RAM 付费一整天(红色突出显示的区域)。 ![]() JEP 346 为这个问题提供了一个答案。当应用程序不活动时,会定期启动并发垃圾收集周期,释放任何可能不再需要的内存。 默认情况下,此功能处于禁用状态。您可以通过为 G1 提供一个毫秒间隔来检查是否需要启动此类周期(使用 -XX:G1PeriodicGCInterval 参数)来激活它。这样它将快速检索内存。 ![]()
Java 12 中引入了一个新的数字格式化器:CompactNumberFormat。基于特定区域提供的模式,它旨在以更短的格式表示数字。 我们可以通过 NumberFormat 类的 getCompactNumberInstance 方法获取其实例。 如前所述,locale 参数负责提供适当的格式模式。格式样式有两种选项:SHORT 和 LONG。让我们以美国区域的数字 1000 为例来更好地理解格式样式。LONG 格式将是“10,000”,而 SHORT 格式将是“10K”。 让我们看一个使用两种不同样式压缩本文点赞数的示例: transform(Function f) transform(Function f) 方法将指定的函数应用于该字符串。只能将一个字符串值传递给指定的函数,然后该函数将输出对象。为了更好地理解此方法,让我们看一个示例。
现在我们将讨论实验性和预览性功能,即仍在开发中的功能,这些功能可能会根据 Java 社区的反馈在最终发布前进行更改。 我们将引用发布相应功能的 Java 版本作为“生产就绪”,而不是详细介绍这些功能。 Switch 表达式(预览) 让我们以一个示例来对比之前和新的 switch 语句。基于 LocalDate 实例的 DayOfWeek 枚举,我们将使用它们来区分工作日和周末。 JDK 增强提案 325 允许我们通过使用箭头符号和逗号分隔多个 case 来消除 switch 语句中容易出错的 break 语句。 现在让我们用其他表达式来检查相同的逻辑: 新的 switch 语句不仅更短、更易读。它们还消除了对 break 语句的需求。在第一次匹配之后,代码执行不会失败。 另一个重要区别是我们可以直接将 switch 语句应用于变量。以前,这是不可行的。 Switch 表达式也可以在不产生结果的情况下运行代码。 值得注意的是,我们可以选择使用旧语法或新语法。Java 12 中的 Switch 表达式只是一个附加功能,它们不会替代任何现有功能。 Switch 表达式将在 Java 14 中准备好投入生产。关于 switch 表达式的主要文章包含您需要了解的有关它们的所有信息。 在 Java 12 中,必须在 IDE(IntelliJ 可通过 FileProject StructureProject SettingsProjectProject language level 完成)中启用 Switch 表达式,或者在使用 javac 和 java 命令时使用 -enable-preview 参数。 Unicode 11在 Java 11 支持 Unicode 10 之后,Java 12 将该支持升级为包含 Unicode 11。这意味着 String 和 Character 类尤其必须能够处理 Unicode 11 新增的字符、代码块和脚本。 有关示例,请参阅前面引用的 Unicode 10 部分。 (Unicode 11 兼容性不包含在任何 JDK 增强提案中。) Microbenchmark Suite到目前为止,JDK 类库的微基准测试一直作为一个独立项目处理。例如,使用这些测试来验证 JDK 方法在新的 Java 版本中并没有变慢。它们会定期评估 JDK 类库的性能。 为了方便测试的执行和演进,JDK 增强提案 230 将当前的微基准测试集集成到 JDK 源代码中。
在编译 .java 文件时出现的常量包含在.class 文件的常量池中。这些常量包括引用的类和方法的名称(例如“java/lang/System”、“out”和“println”),以及 Java 代码中定义的常量,例如字符串“Hello world!”。每个常量都被赋予一个在 .class 文件字节码中引用的数字。 JDK 增强提案 334 将使创建读取或写入 JVM 字节码的 Java 程序变得更加容易。为此,它提供了新的类和接口来表示常量池中的元素。 作为类和方法引用的常量会增加复杂性。由于我们只知道所引用类和方法的名称、参数和返回类型,因此我们无法使用反射类 Class 和 MethodHandle。 现在可以使用 ClassDesc、MethodHandleDesc 和 MethodTypeDesc 等类来标识类和方法,等等。 结论Java 12 中的修改相当容易处理。现在可以使用 Teeing Collector,它允许我们用两个收集器终止 Stream 并合并它们的结果,以及一些其他的 String 和 Files 方法。 由于 64 位系统上可用的 classes.jsa 共享存档文件,类数据共享现在默认启用。 如果 G1 垃圾收集器花费的时间过长,则可以中断其混合集合。未使用的内存会快速返回给操作系统。 Shenandoah 垃圾收集器和 Switch 表达式是另外两个已集成到 Java 12 中的实验性或预览性功能。 |
在 Java 中,根据指定条件(通常由谓词封装)选择性地从 List 中移除元素,是编程中的常见任务。当开发人员必须过滤掉不符合特定标准的元素时,此操作至关重要,可提高效率和相关性。
阅读9分钟
Java 8 于 2014 年发布,为 Java 编程语言带来了变革。在其众多新功能和改进中,最显著的添加之一是 Stream API 和多功能 Stream Collectors 的引入。这些增强功能使得使用...更加容易。
阅读 3 分钟
当 I/O 操作尝试发生在已关闭的通道上,或者通道对预期操作已关闭时,会触发 ClosedChannelException 类。也就是说,如果抛出此异常。然而,这并不意味着通道已完全关闭,只是意味着...
阅读 4 分钟
Permutation Java 要确定序列元素的字典序排列,请应用排列方法。它指的是按字典序将数组的项重新排列为下一个更大的排列。重新排列项以产生字典序排列是基础...
阅读 6 分钟
超文本传输协议(HTTP)支持多种方法来在服务器上执行任何任务或从服务器接收任何数据。Java 的 Get 和 Post 方法是 HTTP 中用于从服务器发送和接收数据的两种重要方法。尽管这两种方法...
阅读 6 分钟
Java 中的按位与 (&) 和逻辑与 (&&) 运算符之间的区别 在 Java 中,&(按位与)和 &&(逻辑与)运算符具有不同的目的和行为。虽然两个运算符都涉及 AND 的概念,但它们应用于不同的上下文。按位与 (&) 运算符 单一 AND……
阅读 4 分钟
在本节中,我们将学习什么是 Adam 数,并创建 Java 程序来检查给定的数是否为 Adam 数。Adam 数程序经常在 Java 编码测试和学术界中被问到。Adam 数:如果一个数满足...,则称该数为 Adam 数。
阅读 3 分钟
数字图像分析和计算机视觉都严重依赖于图像处理。为了获得预期的结果,这需要图像的修改。Java 有许多功能强大且特性丰富的库。使用它们,我们可以操纵图像。图像方向的操纵...
阅读 6 分钟
Java 中的考试座位安排涉及设计一个程序,为学生分配考场座位,确保公平性和遵守特定规则,例如通过分隔朋友或相似的准考证号来防止作弊。它通常包括排序、网格分配和以编程方式应用约束...
阅读9分钟
当我们看到错误消息“Java is started by returned exit code 1”时,这意味着运行 Java 程序时出现了问题。退出代码“1”是通用的错误代码,表示 Java 在启动时遇到问题并且……
阅读 4 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India