拓展阅读

Java Functional java 函数式编程

Java Lambda

jdk17 有哪些新特性

JDK 17 引入了多项新特性和改进,以下是 JDK 17 的一些主要新特性:

  1. 模式匹配的 switch(JEP 406):作为第二次预览版,这个特性增强了 switch 语句,允许使用模式匹配来简化 switch 语句中的复杂逻辑。

  2. 密封类(JEP 409):密封类正式成为 Java 语言的一部分,允许开发者定义受限的类层次结构,限制哪些类可以实现特定的接口或者继承特定的类。

  3. 删除实验性的 AOT 和 JIT 编译器(JEP 410):Java 17 移除了 Java 9 引入的实验性 AOT 和 JIT 编译器,保留了 JVM 编译器接口 (JVMCI)。

  4. 弃用安全管理器以进行删除(JEP 411):安全管理器被弃用,并计划在将来的版本中删除,因为它已不是保护 Java 代码的主要方法。

  5. 外部函数和内存 API(JEP 412):作为孵化 API,这个特性允许 Java 程序更安全、高效地与 Java 运行时之外的代码和数据进行互操作。

  6. 向量 API(JEP 414):第二轮孵化,提供对 SIMD 指令的支持,以便在 Java 中执行向量计算。

  7. 恢复始终严格的浮点语义(JEP 306):更新了浮点数的舍入模式和异常处理,以确保 Java 程序在不同的平台上都能有一致的行为。

  8. 增强的伪随机数生成器(JEP 356):增加了新的接口类型和实现,改善了随机数生成器的性能和灵活性。

  9. 新的 macOS 渲染管道(JEP 382):Java 2D API 现在可以使用 Apple Metal 加速渲染 API,提升了在 macOS 上的渲染性能。

  10. macOS/AArch64 端口(JEP 391):为 macOS AArch64 架构提供了官方支持。

  11. 删除已弃用的 Applet API(JEP 398):从 JDK 中移除了 Applet API,因为它已经被弃用多年。

  12. 强封装 JDK 内部元素(JEP 403):进一步限制了对 JDK 内部元素的访问,推动开发者使用标准 API。

  13. Context-Specific Deserialization Filters(JEP 415):增加了对反序列化操作的细粒度控制,提高了安全性。

  14. 支持在 Keytool -genkeypair 命令中指定签名者(JEP 未明确提及):增强了 keytool 工具,允许在生成密钥对时指定签名者。

  15. SunJCE 提供程序通过 AES 密码支持 KW 和 KWP 模式(JEP 未明确提及):增强了加密功能,支持新的加密模式。

  16. 具有系统属性的可配置扩展(JEP 未明确提及):允许通过系统属性配置 TLS 扩展的使用。

  17. DatagramSocket 可以直接加入多播组(JEP 未明确提及):更新了 java.net.DatagramSocket,支持多播组的加入和离开。

这些新特性和改进体现了 JDK 17 在性能、安全性、易用性和现代化方面的持续进步。开发者应当关注这些变化,以确保他们的应用程序能够利用 JDK 17 引入的新特性和改进。

以下是根据您提供的信息,按照指定格式列出的 JDK 17 的新特性:

jdk17 模式匹配的 switch(JEP 406)

JDK 17 引入了 JEP 406:模式匹配的 switch(Pattern Matching for switch),作为一项预览功能,这个特性在 JDK 16 中首次提出,并在 JDK 17 中继续作为预览版进行改进。

以下是 JDK 17 中模式匹配的 switch(JEP 406)的详细介绍:

  1. 模式匹配的扩展:在 JDK 17 中,模式匹配的概念从 instanceof 关键字扩展到了 switch 语句。这意味着可以在 switch 语句中使用模式来对变量进行类型检查和变量声明。

  2. 语法增强:通过模式匹配,switch 语句可以更加灵活地处理不同类型的数据。开发者可以使用类型模式来简化代码,提高可读性。

  3. 预览特性:尽管模式匹配的 switch 是一个有前景的特性,但它在 JDK 17 中仍然是预览特性,这意味着它的语法和行为可能会在 JDK 的未来版本中发生变化。

  4. 使用示例
    Object obj = //...
    switch (obj) {
        case String s -> System.out.println("It's a string: " + s);
        case Integer i -> System.out.println("It's an int: " + i);
        default -> System.out.println("It's something else");
    }
    

    在这个例子中,switch 语句可以根据 obj 的类型执行不同的操作。

  5. 与 instanceof 的结合:模式匹配的 switch 可以与 instanceof 结合使用,提供一种更简洁的方式来处理类型检查和变量赋值。

  6. 增强的表达力:这个特性允许开发者用更少的代码表达更复杂的条件逻辑,特别是在涉及到数据导向的查询时。

  7. 编译器检查:在模式匹配的 switch 中,Java 编译器会检查类型覆盖,确保所有的分支都能妥善处理,增强了代码的健壮性。

  8. 空值处理:模式匹配的 switch 也能妥善处理空值,提供了一种机制来检查和处理空引用,进一步提高了代码的安全性。

  9. 未来展望:作为预览特性,JEP 406 允许社区和开发者提前体验并提供反馈,以便在它成为正式特性时更加健壮和实用。

JEP 406 的引入为 Java 语言增加了一种新的数据结构处理方式,使得 switch 语句的使用更加灵活和功能丰富。尽管目前仍是预览特性,但它展示了 Java 语言在语法和语义上的持续进步和创新。

jdk17 密封类(JEP 409)

JEP 409 引入了 JDK 17 中的一个重要特性,即“密封类”(Sealed Classes)。密封类是一种新的类和接口的声明形式,它限制了谁可以继承或实现它,从而提供了更加严格的类型层次结构和更安全的面向对象设计。

密封类(Sealed Classes)简介

密封类通过 sealed 关键字进行声明,其目的是为了控制一个类的子类或接口的扩展。通过明确指定允许扩展的类或接口列表,密封类提供了一种更加受限制的继承模型,这有助于提高代码的可维护性、可读性和安全性。

密封类的主要特性

  1. 限制继承:只有在密封类内部声明的类或接口才能继承或实现它。

  2. 提高安全性:通过限制继承和实现,可以更好地控制和管理类的层次结构,减少意外或恶意的继承。

  3. 增强模块化:密封类有助于定义和维护清晰、可预测的 API 和组件接口,从而提高代码的模块化和可组合性。

使用示例

以下是一个简单的密封类示例:

public sealed class Shape permits Circle, Rectangle {
    // ...
}

public final class Circle extends Shape {
    // ...
}

public final class Rectangle extends Shape {
    // ...
}

在上述示例中,Shape 是一个密封类,它只允许 CircleRectangle 这两个类来继承它。

迁移建议

  • 评估现有代码:评估现有的类层次结构,确定哪些类或接口适合使用密封类进行限制。

  • 更新文档和教程:提供有关密封类的详细文档、教程和最佳实践,帮助开发者了解和使用这一特性。

  • 进行代码审查:审查和更新现有代码,以利用密封类的安全性和可维护性优势。

结论

JEP 409 的密封类为 Java 引入了一种新的、更加受限制的类和接口声明形式,它有助于提高代码的安全性、模块化和可维护性。

通过明确限制继承和实现,密封类提供了一种更加严格和可控的类型层次结构,从而为开发者提供了一种更加安全和高效的编程方式。

这一特性不仅有助于提高代码的质量和安全性,还将推动 Java 语言的持续创新和进步。

jdk17 删除实验性的 AOT 和 JIT 编译器(JEP 410)

JEP 410 在 JDK 17 中提议删除实验性的 AOT(Ahead-of-Time)和 JIT(Just-In-Time)编译器。这两种编译器都是 Java 虚拟机(JVM)的关键组件,负责将 Java 字节码编译成机器代码以提高执行速度。然而,在 JDK 9 和 JDK 10 中引入的实验性 AOT 和 JIT 编译器没有达到预期的稳定性和性能目标,因此决定在后续版本中将其删除。

实验性的 AOT 和 JIT 编译器简介

  1. AOT 编译器:Ahead-of-Time 编译器在应用程序启动前将 Java 字节码编译成本地机器代码。这种编译方式可以提高应用程序的启动速度和执行速度,但可能会增加应用程序的启动时间和内存占用。

  2. JIT 编译器:Just-In-Time 编译器在应用程序运行时将热点代码(即频繁执行的代码)编译成机器代码。这种编译方式可以提高应用程序的执行速度,但可能会增加编译延迟和编译器开销。

删除实验性的 AOT 和 JIT 编译器的原因

  1. 稳定性问题:实验性的 AOT 和 JIT 编译器在 JDK 9 和 JDK 10 中遇到了多个稳定性和性能问题,这影响了它们在实际生产环境中的可用性。

  2. 性能问题:尽管 AOT 和 JIT 编译器在某些场景下可以提高性能,但它们在其他场景下可能会导致性能下降或不稳定。

  3. 复杂性:维护实验性的 AOT 和 JIT 编译器增加了 JVM 的复杂性,而这并没有带来相应的稳定性和性能优势。

迁移建议

  • 使用默认编译器:在 JDK 17 及以上版本中,开发者应使用默认的 C2 JIT 编译器,它经过了长时间的验证和优化,提供了可靠和高性能的执行环境。

  • 性能评估:如果应用程序依赖于实验性的 AOT 或 JIT 编译器的特定性能特性,开发者应重新评估其性能需求,并可能需要进行相应的代码优化或架构调整。

  • 更新文档和教程:更新相关文档和教程,提供有关实验性 AOT 和 JIT 编译器移除的详细信息和迁移指南,帮助开发者顺利过渡到新的执行环境。

结论

JEP 410 的实验性 AOT 和 JIT 编译器的移除标志着 JDK 团队对于 Java 性能和稳定性的持续追求。

虽然 AOT 和 JIT 编译器提供了一种有前景的性能优化路径,但由于存在的稳定性和性能问题,决定将其移除以确保 JVM 的稳定性、可靠性和一致性。

对于开发者来说,这意味着需要根据自身应用程序的性能需求重新评估编译器选择,并可能需要进行一些代码和架构的调整以适应新的执行环境。

jdk17 弃用安全管理器以进行删除(JEP 411)

JEP 411 提议在 JDK 17 中弃用安全管理器(Security Manager)并计划在未来的 JDK 版本中将其删除。安全管理器是 Java 平台的一个关键组件,用于控制应用程序对于系统资源和操作的访问权限,以提供一定程度的安全性和隔离性。

安全管理器(Security Manager)简介

安全管理器是一个 Java 类,它允许应用程序通过安全策略文件(.policy 文件)定义访问权限和权限控制规则。安全管理器通过安全策略来限制应用程序的能力,以防止恶意代码或不受信任的代码执行危险操作。

弃用安全管理器的原因

  1. 安全模型演进:随着 Java 平台和生态系统的发展,安全模型也在不断演进。现代的安全框架和机制(如沙箱执行、模块化安全、JEP 411 中的 Context-Specific Deserialization Filters 等)提供了更为先进和灵活的安全控制。

  2. 复杂性和性能开销:安全管理器的存在增加了 Java 运行时的复杂性和性能开销,可能会对应用程序的执行性能产生影响。

  3. 废弃和替代:随着其他安全机制和工具的出现(如 Java Platform Module System、安全性增强的 API 和框架等),安全管理器在某些场景下的必要性和价值逐渐减少。

弃用和删除的影响

  • 迁移工作:为了准备未来版本中安全管理器的删除,开发者需要评估和更新现有的安全策略和权限设置,以确保应用程序在没有安全管理器的环境中仍能正常运行。

  • 更新文档和指导:需要更新相关的文档、教程和最佳实践指导,提供关于安全管理器弃用和替代机制的详细信息和迁移建议。

  • 维护和支持:在安全管理器被正式删除之前,可能仍需要进行一段时间的维护和支持,确保兼容性和安全性。

迁移建议

  • 重新评估安全需求:根据应用程序的安全需求和使用场景,重新评估和调整安全策略,使用现代的安全机制和工具替代安全管理器。

  • 遵循最佳实践:遵循 Java 平台和 JDK 的安全最佳实践,更新应用程序的安全策略和配置,以确保安全性和合规性。

  • 测试和验证:在进行任何安全策略和配置的更改后,进行充分的测试和验证,确保应用程序的功能和性能不受影响。

结论

JEP 411 的安全管理器弃用和删除标志着 Java 平台安全模型的演进和优化。

尽管安全管理器在过去提供了一定程度的安全保护,但随着技术的发展和安全需求的变化,它逐渐显得不再适应现代应用程序的安全要求。开发者需要根据应用程序的实际需求和安全风险重新评估和调整安全策略,以利用更为先进和灵活的安全机制,确保应用程序的安全性和可靠性。

jdk17 外部函数和内存 API(JEP 412)

JEP 412 在 JDK 17 中引入了外部函数和内存 API(Foreign Function & Memory API,通常简称为 F&MAPI)。这个新的 API 提供了一种标准化的方式,用于与本地代码(例如 C、C++)进行交互,以及管理直接内存访问,这对于那些需要与底层系统或其他语言进行紧密集成的应用程序特别有用。

外部函数和内存 API(F&MAPI)简介

外部函数和内存 API 的设计目标是提供一种安全、高效和平台独立的方式,用于执行以下操作:

  1. 调用本地函数:允许 Java 代码直接调用本地(native)函数,无需使用 JNI(Java Native Interface)。

  2. 访问直接内存:提供直接访问和操作本地内存的能力,包括分配、释放和读写操作。

主要特性

  1. 安全性:通过类型安全和资源管理功能,提供了一种更加安全和可靠的方式来执行本地函数调用和内存操作。

  2. 性能:减少了 JNI 调用的开销,提供了更高效的本地函数调用和内存访问机制。

  3. 平台独立性:通过提供一个统一的 API,使得应用程序可以在不同的平台上使用相同的代码,无需进行平台特定的修改或优化。

  4. 灵活性:支持复杂的数据结构和交互模式,包括结构体、数组、回调函数等。

使用示例

以下是一个简单的使用外部函数和内存 API 的示例:

import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemorySegment;

public class ExternalFunctionExample {
    public static void main(String[] args) {
        try (MemorySegment segment = MemorySegment.allocateNative(1024)) {
            MemoryAddress address = segment.address();
            // 使用外部函数写入内存
            writeToMemory(address);
            // 使用外部函数从内存读取数据
            int value = readFromMemory(address);
            System.out.println("Read value from memory: " + value);
        }
    }

    private static native void writeToMemory(MemoryAddress address);

    private static native int readFromMemory(MemoryAddress address);
}

在上述示例中,我们首先分配了一个本地内存段,然后使用外部函数(native 方法)进行数据的写入和读取。

迁移建议

  • 替代 JNI:考虑使用 F&MAPI 替代传统的 JNI 调用,以提高性能和简化本地代码的编写和维护。

  • 安全性和验证:在使用外部函数和内存 API 时,确保遵循安全最佳实践,并进行充分的测试和验证,以确保应用程序的稳定性和安全性。

  • 文档和教程更新:更新相关的文档、教程和示例代码,提供有关 F&MAPI 的详细信息、使用指南和最佳实践,以帮助开发者了解和有效利用这一新特性。

结论

JEP 412 的外部函数和内存 API 为 Java 提供了一种新的、现代化的方式,用于与本地代码进行交互和管理直接内存访问。

这一新特性不仅有助于提高性能和简化开发,还为那些需要与其他语言或底层系统进行紧密集成的应用程序提供了更大的灵活性和扩展性。

对于那些寻求提高性能、简化编程和加强与底层系统集成的开发者来说,外部函数和内存 API 提供了一种强大而灵活的工具,值得深入研究和应用。

jdk17 向量 API(JEP 414)

JEP 414 引入了 JDK 17 的一个重要特性:向量 API(Vector API)。这一新特性旨在提供一种简单、高效且可移植的方式来编写复杂的数学和科学计算代码,特别是那些涉及并行计算和 SIMD(单指令多数据流)指令集的任务。

向量 API(Vector API)简介

向量 API 为 Java 引入了一组新的类和方法,允许开发者以面向向量的方式进行数学运算和数据处理。这些向量操作允许在单个指令中并行处理多个数据元素,从而提高计算性能和效率。

主要特性

  1. 并行处理:通过利用 SIMD 指令集,向量 API 允许在单个操作中处理多个数据元素,提高计算密集型应用程序的性能。

  2. 类型安全:提供了一组类型安全的向量数据类型,包括整数、浮点数和布尔值等,以及相应的算术和逻辑操作。

  3. 可移植性:向量 API 的设计考虑了多种硬件平台,包括 CPU、GPU 和其他加速器,从而提供了一种高度可移植的并行计算解决方案。

  4. 简化开发:通过提供高级的数学和数据处理操作,向量 API 简化了并行和向量化代码的编写和维护。

使用示例

以下是一个简单的向量 API 使用示例,展示了如何使用向量操作进行元素级的加法运算:

import jdk.incubator.vector.*;

public class VectorExample {
    public static void main(String[] args) {
        try (VectorSpecies<Float> species = FloatVector.SPECIES_256) {
            FloatVector a = FloatVector.fromArray(species, new float[]{1.0f, 2.0f, 3.0f, 4.0f}, 0);
            FloatVector b = FloatVector.fromArray(species, new float[]{4.0f, 3.0f, 2.0f, 1.0f}, 0);

            FloatVector result = a.add(b);

            float[] array = new float[species.length()];
            result.intoArray(array, 0);

            for (float f : array) {
                System.out.println(f);
            }
        }
    }
}

在这个示例中,我们首先创建了两个浮点数向量 ab,然后使用 add 方法计算它们的和,并将结果存储在 result 向量中。

迁移建议

  • 替代现有代码:考虑将现有的数学和科学计算代码替换为向量 API,以利用其提供的并行和向量化优势。

  • 性能优化:分析应用程序的性能瓶颈,特别是那些计算密集型任务,看看是否可以通过向量化来提高性能。

  • 学习和培训:提供关于向量 API 的文档、教程和培训材料,帮助开发者了解和利用这一新特性。

结论

JEP 414 的向量 API 为 Java 开发者提供了一种强大而灵活的工具,用于进行高性能的数学和科学计算。

通过利用 SIMD 指令集和并行处理能力,向量 API 可以显著提高计算密集型应用程序的性能和效率。

对于需要进行复杂计算和数据处理的应用程序,向量 API 提供了一种现代化、高效且可移植的解决方案,值得开发者深入研究和应用。

jdk17 恢复始终严格的浮点语义(JEP 306)

JEP 306 旨在 JDK 17 中恢复始终严格的浮点语义。这一变更是对 JDK 12 中引入的 JEP 326 的反转,JEP 326 允许了在某些场景下的 JVM 实现中放宽浮点操作的精确性以提高性能。

始终严格的浮点语义

在计算机科学中,浮点数的精确性和一致性是一个经常讨论的主题。由于硬件和软件实现的限制,浮点数的运算可能会产生舍入误差和不一致的结果。JEP 306 的目标是确保在所有情况下都提供一致和可预测的浮点运算结果,即始终遵循 IEEE 754 浮点算术标准。

主要特性

  1. 提高一致性:恢复始终严格的浮点语义有助于提高 Java 应用程序的一致性和可预测性。

  2. 增强可靠性:通过确保浮点运算的精确性,JEP 306 增强了计算结果的可靠性和正确性。

  3. 保持兼容性:JEP 306 设计为与现有的 JVM 实现和代码基础兼容,以减少可能的兼容性问题。

影响

  • 性能影响:由于恢复了严格的浮点语义,可能会有一定的性能开销。但这种开销通常是可接受的,尤其是考虑到提供更一致和可预测的结果的重要性。

  • 应用程序行为:对于依赖于浮点数精确性的应用程序,如科学计算和金融应用,可能需要进行一些调整以适应新的浮点语义。

迁移建议

  • 代码审查:审查应用程序的浮点数运算,确保它们满足新的严格浮点语义。

  • 测试和验证:进行充分的测试和验证,确保应用程序在新的 JVM 实现中的浮点数运算表现正常。

  • 性能优化:根据应用程序的实际需求和性能指标,进行必要的性能优化和调整。

结论

JEP 306 的始终严格的浮点语义变更旨在提供一致、可预测和可靠的浮点运算结果,以满足特定应用程序和工作负载的精确性要求。

尽管这可能会带来一些性能开销,但它为 Java 提供了一种更为稳定和可靠的浮点数处理方式。开发者需要根据应用程序的需求和性能指标进行相应的调整和优化,以确保代码的正确性和性能表现。

jdk17 增强的伪随机数生成器(JEP 356)

JEP 356 在 JDK 17 中引入了增强的伪随机数生成器(PRNG,Pseudo-Random Number Generator)功能。这一变更旨在提供更强大、更灵活、更安全的随机数生成能力,以满足不同应用场景和安全要求。

增强的伪随机数生成器(PRNG)简介

伪随机数生成器是一种算法,用于生成看似随机但实际上是基于初始种子的数字序列。在计算机科学和密码学中,高质量的 PRNG 是至关重要的,因为它们用于各种应用,如模拟、加密、安全哈希和游戏等。

主要特性

  1. 多种算法支持:增强的 PRNG 提供了多种高质量的随机数生成算法,包括 Xoshiro、Xoroshiro 和 SplitMix 等。

  2. 灵活性:开发者可以选择不同的 PRNG 算法和参数,以满足特定的随机数生成需求和性能要求。

  3. 安全性增强:提供了更强的密码学安全性和预测性,以保护敏感信息和系统。

  4. 性能优化:通过底层优化和并行处理,提高了随机数生成的效率和吞吐量。

使用示例

以下是一个简单的使用增强的 PRNG 的示例:

import java.util.Random;

public class EnhancedPRNGExample {
    public static void main(String[] args) {
        // 使用默认的 PRNG 算法
        Random random = new Random();

        // 生成随机整数
        int randomNumber = random.nextInt(100);
        System.out.println("Random number: " + randomNumber);

        // 使用 Xoshiro 算法
        Random xoshiroRandom = RandomGeneratorFactory.createXoshiroRandom();
        int xoshiroNumber = xoshiroRandom.nextInt(100);
        System.out.println("Xoshiro random number: " + xoshiroNumber);
    }
}

在这个示例中,我们首先使用 Java 的标准 Random 类生成一个随机整数,然后使用增强的 Xoshiro PRNG 算法生成另一个随机整数。

迁移建议

  • 替代现有代码:考虑将现有的随机数生成代码替换为增强的 PRNG,以提供更好的性能和安全性。

  • 配置和调优:根据应用程序的随机数需求和性能指标,选择合适的 PRNG 算法和参数进行配置和调优。

  • 测试和验证:进行充分的测试和验证,确保应用程序在新的 PRNG 实现中的随机数生成表现正常,并满足安全和性能要求。

结论

JEP 356 的增强的伪随机数生成器功能为 Java 开发者提供了一种先进、灵活和安全的随机数生成解决方案。

通过提供多种高质量的 PRNG 算法和增强的安全性特性,增强的 PRNG 可以满足各种复杂应用和安全需求。

开发者应根据应用程序的具体需求和性能指标,合理选择和配置 PRNG 算法,以确保随机数生成的高效、安全和可靠。

jdk17 新的 macOS 渲染管道(JEP 382)

JEP 382 引入了 JDK 17 的新 macOS 渲染管道,这一变更旨在利用 Apple Metal 图形和计算框架,提供更高效、更灵活的图形渲染和窗口系统支持。

新的 macOS 渲染管道简介

新的 macOS 渲染管道利用了 Apple Metal 技术,这是一种现代的图形和计算框架,提供了优化的性能和功能,以满足现代图形应用程序的需求。

主要特性

  1. 性能优化:通过利用 Metal 的底层优化和并行处理能力,提高了图形渲染和窗口系统的性能。

  2. 更高的图形质量:新的渲染管道提供了更高质量的图形渲染,包括更精确的颜色管理和更高分辨率的渲染。

  3. 灵活性和扩展性:支持更多的图形特性和效果,以及更复杂的图形渲染技术,如光线追踪和实时渲染。

  4. 更好的硬件支持:新的渲染管道提供了对最新硬件特性的支持,包括更先进的 GPU 计算和图形加速技术。

使用示例

由于新的 macOS 渲染管道主要是为内部实现而设计的,因此开发者不需要直接与其交互。但是,开发者可以期待更好的图形性能和质量,无需进行任何特殊的配置或调整。

迁移建议

  • 更新到最新版本:确保使用最新的 JDK 17 版本,以获得新的 macOS 渲染管道的所有优势。

  • 性能和质量检测:对现有的图形应用程序进行性能和质量测试,以评估新渲染管道带来的改进。

  • 问题报告和反馈:如果在使用新的 macOS 渲染管道时遇到任何问题或异常,及时报告给 JDK 团队,以帮助改进和优化。

结论

JEP 382 的新 macOS 渲染管道引入了一系列重要的性能和质量改进,利用 Apple Metal 技术提供了更高效、更灵活的图形渲染和窗口系统支持。

这一变更不仅提高了图形应用程序的性能和质量,还为开发者提供了更先进和可靠的图形技术,以满足现代应用和用户的需求。

尽管大多数开发者可能不需要直接与新的渲染管道交互,但可以期待在性能、质量和功能方面的明显改进。

jdk17 macOS/AArch64 端口(JEP 391)

JEP 391 引入了 JDK 17 的 macOS/AArch64 端口,这一变更旨在支持 Apple Silicon(如 M1 芯片)上的原生 ARM64 架构,提供更好的性能和兼容性。

macOS/AArch64 端口简介

随着 Apple Silicon 的发布,越来越多的 macOS 设备开始使用 ARM64 架构。为了支持这些新的硬件平台,并提供优化的性能和功能,JEP 391 在 JDK 17 中引入了 macOS/AArch64 端口。

主要特性

  1. 原生 ARM64 支持:支持在 Apple Silicon(如 M1 芯片)上运行的原生 ARM64 代码,提供更好的性能和电池寿命。

  2. 优化的性能:通过利用 ARM64 架构的优势,提高了 Java 应用程序在支持的 macOS 设备上的性能。

  3. 完整的功能兼容性:保持了与现有 x86_64 端口的功能和兼容性,使得现有的 Java 应用程序可以无缝迁移到新的 macOS/AArch64 端口。

  4. 先进的开发者工具:提供了一套先进的开发者工具和资源,以支持 macOS/AArch64 上的 Java 开发和调试。

使用示例

开发者可以像在其他平台上一样使用 JDK 17,无需特殊配置或调整。只需确保使用的是支持 macOS/AArch64 端口的 JDK 版本,并在 Apple Silicon 设备上运行。

迁移建议

  • 升级到 JDK 17:对于使用 Apple Silicon 设备的开发者,建议升级到支持 macOS/AArch64 端口的 JDK 17 版本。

  • 测试应用程序:在新的硬件平台上进行全面的测试,确保 Java 应用程序在 macOS/AArch64 上的兼容性和性能。

  • 性能优化:根据应用程序的实际需求和性能指标,进行必要的优化和调整,以充分利用 ARM64 架构的优势。

结论

JEP 391 的 macOS/AArch64 端口为 Java 开发者提供了对 Apple Silicon(如 M1 芯片)的原生 ARM64 架构的全面支持。

通过引入优化的性能、完整的功能兼容性和先进的开发者工具,这一变更不仅提高了 Java 应用程序在新硬件平台上的性能和可用性,还为开发者提供了一个强大和灵活的开发环境。

对于那些希望利用最新硬件技术,并提供高性能 Java 应用程序的开发者来说,macOS/AArch64 端口是一个非常有价值的更新。

jdk17 删除已弃用的 Applet API(JEP 398)

JEP 398 在 JDK 17 中删除了已弃用的 Applet API,这一决策反映了现代 Web 开发中对 Applet 技术的逐渐减少使用,以及对 Web 浏览器和 Java 插件支持的变化。

删除已弃用的 Applet API 简介

Applet 是 Java 的一个历史组件,用于在 Web 浏览器中运行的小型应用程序。但随着 Web 技术的进步,如 HTML5、JavaScript 和 WebAssembly,Applet 技术已经逐渐失去了其在 Web 开发中的地位。

主要特性

  1. 移除已弃用的 API:JEP 398 移除了 JDK 中的 Applet 相关的已弃用 API,包括 java.applet 包下的类和方法。

  2. 减少安全风险:通过删除不再维护和更新的 Applet API,可以减少与安全相关的潜在风险,因为这些旧 API 可能存在已知的安全漏洞。

  3. 简化代码库:删除不再使用的和维护的代码,有助于简化 JDK 的代码库,使其更易于管理和维护。

影响

  • 向后兼容性:如果您的应用程序依赖于已弃用的 Applet API,那么在升级到 JDK 17 之前,您需要找到替代方案或更新代码以适应新的 API。

  • 迁移和替代方案:开发者需要考虑使用现代的 Web 技术,如 HTML5、JavaScript 和 WebAssembly,作为替代方案来替代 Applet。

迁移建议

  • 检查依赖:检查您的应用程序是否依赖于已弃用的 Applet API,如果有,考虑寻找替代方案。

  • 更新代码:根据实际需求和替代方案,更新和优化使用 Applet 的部分代码。

  • 测试和验证:进行充分的测试和验证,确保在 JDK 17 上更新的应用程序在功能和性能上都达到预期。

结论

JEP 398 的删除已弃用的 Applet API 反映了 Java 平台和 Web 技术的演变,强调了现代 Web 开发中对更先进和安全的技术的需求。

对于那些仍然依赖于 Applet 的旧应用程序,这可能需要一些工作来迁移到更现代的解决方案,但这也提供了一个机会来优化和改进应用程序,以满足当前和未来的 Web 开发需求。

jdk17 强封装 JDK 内部元素(JEP 403)

JEP 403 强封装 JDK 内部元素是 JDK 17 中的一个重要变更,它旨在增强 JDK 内部元素的封装,以提高代码安全性和模块性。

强封装 JDK 内部元素简介

强封装是 Java 语言中的一个重要概念,它有助于控制访问级别,防止不恰当的访问和修改,从而提高代码的可维护性、可扩展性和安全性。JEP 403 主要关注于强化 JDK 内部的封装,确保只有经过严格审查和验证的代码才能访问和修改 JDK 内部元素。

主要特性

  1. 增强安全性:通过限制对 JDK 内部元素的直接访问,提高了代码的安全性,减少了潜在的安全风险和漏洞。

  2. 增强模块性:强封装有助于更好地定义和管理模块边界,提供清晰的接口和实现分离,以支持更灵活、可维护和可扩展的代码结构。

  3. 提高代码质量:通过减少不恰当的访问和修改,有助于提高代码的质量和稳定性,减少错误和异常。

影响

  • 编译和运行:在 JDK 17 中,由于强封装的实施,可能需要更新或修改依赖于 JDK 内部元素的代码。

  • 第三方库和框架:对于使用 JDK 内部 API 的第三方库和框架,可能需要更新到符合强封装规定的版本。

迁移建议

  • 更新依赖:检查您的项目是否使用了 JDK 内部 API,并更新到与 JDK 17 兼容的版本。

  • 代码审查和更新:对于依赖于 JDK 内部元素的代码,进行审查和更新,确保它们符合新的强封装规定。

  • 测试和验证:进行全面的测试和验证,确保更新后的代码在功能、性能和安全性方面都符合预期。

结论

JEP 403 强封装 JDK 内部元素是 JDK 17 的一个关键变更,它强调了 Java 平台对代码安全性、模块性和质量的承诺。

尽管这可能需要一些工作来调整和更新现有的代码和依赖,但这也提供了一个重要的机会来优化和改进应用程序,以满足最新的 Java 开发标准和最佳实践。

通过采纳和遵循强封装规定,开发者可以构建更安全、更可维护和更健壮的 Java 应用程序。

jdk17 Context-Specific Deserialization Filters(JEP 415)

JEP 415 引入了 JDK 17 中的 Context-Specific Deserialization Filters(上下文特定的反序列化过滤器),这是一个重要的安全功能,旨在提高 Java 应用程序对反序列化漏洞的保护。

Context-Specific Deserialization Filters 简介

反序列化漏洞是一种常见的安全威胁,它可能允许攻击者执行远程代码执行(RCE)等攻击,导致应用程序的安全性受到威胁。为了应对这种威胁,JEP 415 引入了上下文特定的反序列化过滤器,允许开发者定义在反序列化过程中允许或拒绝特定类型的对象。

主要特性

  1. 精确的控制:上下文特定的反序列化过滤器允许开发者定义精确的规则,以控制哪些类可以在特定的反序列化上下文中被实例化。

  2. 灵活的配置:开发者可以通过配置文件或编程方式定义过滤规则,以适应各种不同的应用程序需求和安全策略。

  3. 提高安全性:通过减少不受信任的类和对象的实例化,上下文特定的反序列化过滤器有助于降低反序列化漏洞的风险。

使用示例

import java.io.*;
import java.util.*;

public class DeserializeExample {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 创建一个 ObjectInputStream 对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data.ser"));

        // 定义一个反序列化过滤器,只允许特定的类被反序列化
        ois.setObjectInputFilter(filterInfo -> {
            if (filterInfo.serialClass() != null && filterInfo.serialClass().getName().equals("AllowedClass")) {
                return ObjectInputFilter.Status.ALLOWED;
            } else {
                return ObjectInputFilter.Status.REJECTED;
            }
        });

        // 反序列化对象
        Object obj = ois.readObject();
        System.out.println("Deserialized object: " + obj);

        ois.close();
    }
}

在这个示例中,我们定义了一个反序列化过滤器,只允许名为 “AllowedClass” 的类被反序列化。这确保了只有这个特定的类可以在反序列化过程中被实例化。

迁移建议

  • 配置反序列化过滤器:为您的应用程序配置上下文特定的反序列化过滤器,以精确地控制反序列化行为。

  • 更新安全策略:审查并更新现有的安全策略和最佳实践,以利用上下文特定的反序列化过滤器提供的增强安全性。

  • 测试和验证:进行全面的测试和验证,确保新的反序列化过滤器在功能和安全性方面都符合预期。

结论

JEP 415 的上下文特定的反序列化过滤器为 Java 应用程序提供了一个强大的工具,用于提高对反序列化漏洞的保护。

通过精确的控制和灵活的配置,开发者现在可以更好地保护其应用程序免受潜在的反序列化攻击。

jdk17 支持在 Keytool -genkeypair 命令中指定签名者

JEP 411 引入了 JDK 17 中对 Keytool 工具的改进,其中最主要的变化是增强了 -genkeypair 命令,使其能够支持在命令行中直接指定签名者信息。

支持在 Keytool -genkeypair 命令中指定签名者简介

在 JDK 17 中,通过增强 Keytool 工具的 -genkeypair 命令,开发者现在可以在一条命令行指令中直接指定证书请求的签名者信息,而不必依赖交互式提示或额外的配置文件。

主要特性

  1. 直接指定签名者信息:现在可以在 Keytool -genkeypair 命令中使用新的选项(如 -sigalg-validity-ext 等)直接指定证书请求的签名者信息。

  2. 简化证书生成流程:通过在命令行中直接提供签名者信息,简化了证书生成流程,减少了手动输入和配置的需要。

  3. 提高效率:这一改进使得证书生成过程更加高效,特别是在自动化脚本和批处理任务中。

使用示例

以下是一个使用新的 Keytool -genkeypair 命令选项来生成证书的示例:

keytool -genkeypair -alias myAlias -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -validity 365 -keystore myKeystore.jks

在这个示例中:

  • -alias myAlias:指定别名为 myAlias
  • -keyalg RSA:选择 RSA 密钥算法。
  • -keysize 2048:指定密钥大小为 2048 位。
  • -sigalg SHA256withRSA:选择使用 SHA256withRSA 作为签名算法。
  • -validity 365:指定证书有效期为 365 天。
  • -keystore myKeystore.jks:指定密钥库文件为 myKeystore.jks

迁移建议

  • 更新脚本和工具:如果您有自动化脚本或工具使用 Keytool -genkeypair 命令,需要更新它们以使用新的命令选项。

  • 测试证书生成:在生产环境之前,进行全面的测试以确保新的 -genkeypair 命令选项能够按预期生成证书。

  • 更新文档和指南:更新相关的文档、指南和最佳实践,以反映这些新的命令选项。

结论

JEP 411 的改进使得 Keytool -genkeypair 命令更加强大和灵活,为开发者提供了一个更加便捷和高效的方式来生成证书。

通过直接在命令行中指定签名者信息,开发者现在可以更加灵活地控制证书生成过程,从而满足不同的安全需求和使用场景。

jdk17 SunJCE 提供程序通过 AES 密码支持 KW 和 KWP 模式

JEP 411 引入了 JDK 17 中对 SunJCE 提供程序的改进,其中包括支持通过 AES 密码来实现 Key Wrap (KW) 和 Key Wrap with Padding (KWP) 模式。

SunJCE 提供程序通过 AES 密码支持 KW 和 KWP 模式简介

JDK 的 SunJCE(Sun Java Cryptography Extension)提供程序是 Java 的标准加密扩展,用于支持各种加密算法和操作模式。JEP 411 主要关注于增强 SunJCE 提供程序,以支持 AES 密码通过 Key Wrap (KW) 和 Key Wrap with Padding (KWP) 模式。

主要特性

  1. 支持 AES 密码:通过 AES 密码,SunJCE 提供程序现在可以支持 Key Wrap (KW) 和 Key Wrap with Padding (KWP) 模式,这为加密和解密操作提供了更多的灵活性和选项。

  2. 增强加密功能:这一改进增强了 SunJCE 提供程序的加密能力,使其能够处理更复杂和多样化的加密需求,特别是在处理密钥和敏感信息时。

  3. 提高安全性:支持 KW 和 KWP 模式可以提高加密操作的安全性,特别是在密钥管理和保护方面,有助于防止密钥泄露和不当使用。

使用示例

以下是一个使用 AES 密码和 KW 模式进行加密和解密的简单示例:

import javax.crypto.*;
import java.security.*;

public class AESKeyWrapExample {
    public static void main(String[] args) throws Exception {
        // 初始化 AES 密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256);
        SecretKey secretKey = keyGen.generateKey();

        // 创建 Cipher 实例并设置为 KW 模式
        Cipher cipher = Cipher.getInstance("AESWrap");
        cipher.init(Cipher.WRAP_MODE, secretKey);

        // 加密密钥
        byte[] wrappedKey = cipher.wrap(secretKey);
        System.out.println("Wrapped key: " + javax.xml.bind.DatatypeConverter.printHexBinary(wrappedKey));

        // 解密密钥
        cipher.init(Cipher.UNWRAP_MODE, secretKey);
        SecretKey unwrappedKey = (SecretKey) cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
        System.out.println("Unwrapped key: " + javax.xml.bind.DatatypeConverter.printHexBinary(unwrappedKey.getEncoded()));
    }
}

在这个示例中,我们使用 AES 密钥生成器创建一个 256 位的密钥,然后使用 AESWrap 模式进行密钥包装和解包操作。

迁移建议

  • 更新加密操作:如果您的应用程序依赖于 SunJCE 提供程序进行加密操作,并希望利用 KW 和 KWP 模式,需要更新相关的加密逻辑和代码。

  • 测试加密功能:在生产环境之前,进行全面的测试以确保新的 KW 和 KWP 模式在功能和安全性方面都符合预期。

  • 更新文档和指南:更新相关的文档、指南和最佳实践,以反映这些新的加密选项和功能。

结论

JEP 411 的改进增强了 SunJCE 提供程序的加密能力,特别是在支持 AES 密码的 KW 和 KWP 模式方面。

通过这一改进,Java 开发者现在可以更加灵活地进行加密操作,满足不同的安全需求和应用场景。

建议开发者积极采纳这一新功能,并根据具体需求进行相应的配置和测试,以确保加密操作的安全性和有效性。

jdk17 具有系统属性的可配置扩展

JEP 412 引入了 JDK 17 中的一个新功能,该功能允许通过系统属性对可配置扩展进行配置。这为开发者提供了一种更加灵活和便捷的方式来管理和定制 Java 的可配置扩展。

具有系统属性的可配置扩展简介

在 JDK 中,可配置扩展是指那些可以通过安装或卸载的方式在运行时加载和卸载的扩展。这些扩展通常位于 $JAVA_HOME/lib/ext 目录下。

JEP 412 的改进主要针对这些可配置扩展,使其能够通过系统属性进行配置。

主要特性

  1. 系统属性配置:通过系统属性,开发者可以更加灵活地配置和管理可配置扩展,无需修改代码或重新编译。

  2. 动态调整:允许在运行时动态地修改和更新可配置扩展的配置,提供了一种即时调整和优化应用程序性能和行为的方法。

  3. 增强可定制性:这一改进增强了 Java 应用程序的可定制性,使开发者能够根据具体需求和环境条件来定制和优化扩展配置。

使用示例

假设我们有一个名为 my-extension.jar 的可配置扩展,并且想要通过系统属性 java.ext.dirs 来指定该扩展的路径。以下是一个使用系统属性来配置可配置扩展路径的示例:

java -Djava.ext.dirs=/path/to/my-extension.jar MyApp

在这个示例中,我们使用 -Djava.ext.dirs=/path/to/my-extension.jar 来指定 my-extension.jar 扩展的路径,然后运行 MyApp 应用程序。

迁移建议

  • 更新扩展配置:如果您的应用程序依赖于可配置扩展,并且希望利用这一新功能,需要更新相关的扩展配置和启动脚本。

  • 测试扩展加载:在生产环境之前,进行全面的测试以确保新的配置方式能够正确加载和使用可配置扩展。

  • 更新文档和指南:更新相关的文档、指南和最佳实践,以反映这一新的配置选项和功能。

结论

JEP 412 的改进为 JDK 17 增加了一种新的方式来配置和管理可配置扩展,通过系统属性提供了更高的灵活性和可定制性。

这一改进使得开发者能够更加方便地调整和优化应用程序的行为,同时提供了一种动态和可配置的扩展管理机制。

jdk17 DatagramSocket 可以直接加入多播组

JEP 414 引入了 JDK 17 中的一个重要改进,该改进允许 DatagramSocket 直接加入多播组。这一改进为多播通信提供了更加便捷和直观的编程接口,使得开发者可以更容易地实现和管理多播通信。

DatagramSocket 可以直接加入多播组简介

多播是一种网络通信模式,其中一个数据包可以同时发送到多个接收者。在 Java 中,多播通常通过多播 IP 地址和端口来实现。在 JDK 17 之前,要使用 DatagramSocket 加入多播组,开发者需要先创建一个 MulticastSocket 对象,然后使用该对象进行多播通信。JEP 414 的改进允许 DatagramSocket 直接加入多播组,简化了多播通信的编程。

主要特性

  1. 直接加入多播组:通过 DatagramSocket 对象,开发者现在可以直接加入和离开多播组,无需创建额外的 MulticastSocket 对象。

  2. 简化多播编程:这一改进使得多播编程更加简洁和直观,减少了代码复杂性和潜在的错误。

  3. 提高灵活性:开发者可以更加灵活地控制和管理多播通信,包括加入多个多播组、设置 TTL(生存时间)等。

使用示例

以下是一个使用 DatagramSocket 直接加入多播组的简单示例:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class MulticastExample {
    public static void main(String[] args) throws Exception {
        // 创建 DatagramSocket 对象
        DatagramSocket socket = new DatagramSocket();

        // 定义多播 IP 地址和端口
        InetAddress group = InetAddress.getByName("224.0.0.1");
        int port = 8888;

        // 加入多播组
        socket.joinGroup(new java.net.InetSocketAddress(group, port), null);

        // 发送数据包
        String message = "Hello, multicast!";
        byte[] buffer = message.getBytes();
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length, group, port);
        socket.send(packet);

        // 离开多播组
        socket.leaveGroup(group);

        // 关闭 socket
        socket.close();
    }
}

在这个示例中,我们创建了一个 DatagramSocket 对象,并使用 joinGroup 方法加入了多播组。然后,我们发送了一个包含 “Hello, multicast!” 消息的数据包,并最后离开了多播组。

迁移建议

  • 更新多播代码:如果您的应用程序使用多播通信,并且希望利用这一新功能,需要更新相关的多播代码和逻辑。

  • 测试多播功能:在生产环境之前,进行全面的测试以确保新的多播功能在功能和性能方面都符合预期。

  • 更新文档和指南:更新相关的文档、指南和最佳实践,以反映这一新的多播配置和功能。

结论

JEP 414 的改进为 JDK 17 增加了 DatagramSocket 直接加入多播组的能力,这一改进使得多播通信更加简洁、直观和灵活。

总结下 jdk17 变化

JDK 17 引入了许多重要的改进和新功能,以下是一些主要的变化:

  1. 密封类(JEP 409):引入了新的 sealed 关键字,允许类、接口和枚举类型限制其子类的使用。

  2. 删除实验性的 AOT 和 JIT 编译器(JEP 410):删除了之前作为实验性质量功能提供的 Ahead-Of-Time (AOT) 和 Just-In-Time (JIT) 编译器。

  3. 弃用安全管理器以进行删除(JEP 411):弃用了安全管理器,并计划在将来的版本中删除它。

  4. 外部函数和内存 API(JEP 412):引入了新的外部函数和内存 API,提供了一种更加灵活和高效的方式来操作外部函数和内存。

  5. 向量 API(JEP 414):引入了新的向量 API,提供了一种高效的方式来执行向量化操作。

  6. 恢复始终严格的浮点语义(JEP 306):恢复了 JDK 1.0 到 1.2 之间使用的严格浮点语义。

  7. 增强的伪随机数生成器(JEP 356):提供了一种更加高效和安全的伪随机数生成器。

  8. 新的 macOS 渲染管道(JEP 382):引入了一个新的 macOS 渲染管道,以提供更好的性能和兼容性。

  9. macOS/AArch64 端口(JEP 391):引入了 macOS 上的 AArch64 架构支持。

  10. 删除已弃用的 Applet API(JEP 398):删除了之前已被弃用的 Applet API。

  11. 强封装 JDK 内部元素(JEP 403):增强了 JDK 内部元素的封装性。

  12. Context-Specific Deserialization Filters(JEP 415):引入了上下文特定的反序列化过滤器,提高了反序列化操作的安全性。

这些变化涵盖了 Java 语言、JVM、库和工具等多个方面,旨在提高性能、安全性、可维护性和开发者体验。