全面解读JDK17新特性

4,385 阅读6分钟

这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

欢迎关注公众号OpenCoder,来和我做朋友吧~❤😘😁🐱‍🐉👀

JDK 17

Java 17 已于2021/09/14正式发布,该版本是自Java 11以来的首个长期支持(LTS)版本。Oracle 还提议将 JDK LTS发布的节奏从每三年一次改为每两年一次,并且每个LTS 版本的服务时间至少8年以上。Java 版本通常是6个月一更新,时间分别在3月和9月,而这些版本的支持时间基本在半年左右。

据Oralce官博透露,虽然6个月版本的使用人数在增长,但大部分组织及企业更倾向于把LTS版本用在生产环境中,从而得到更加稳定可靠的服务。这一点从Snyk发布的2021 Java社区报告中也可以得到证实,虽然有61.5%的人在生产中使用Java 11,但仍有一半的Java 11用户(目前使用最多的版本)在他们的生产堆栈中使用Java 8。

Oracle 推出 Free Java License

自Java被Oralce收购以后,付费JDK就一直被人诟病,现在好了,Oracle 宣布推出JDK免费服务。什么意思呢?让我们来看一下官方解释:

  • Oracle正在为行业提供免费的,领先的Oralce JDK,包括所有季度安全更新,并包含商业和生产用途。
  • 新许可是“Oracle 免费条款和条件”(NFTC) 许可。此Oracle JDK许可证允许所有用户免费使用,甚至可以用于商业和生产用途。只要不收费,再分发是允许的。
  • 开发人员和组织现在无需点击即可轻松下载、使用、共享和重新分发 Oracle JDK。
  • Oracle 将从Oracle JDK 17开始提供这些免费版本和更新,并在下一个 LTS 版本之后继续提供整整一年。以前的版本不受此更改的影响。
  • Oracle 将继续按照自 Java 9 以来的相同版本和时间表提供GPL下的Oracle OpenJDK 版本。

总结成一句话,“免费”也并不意味着开发者可以随心所欲,因为Oracle的 NFTC 是禁止付费重新分发其 Java 软件。

Spring版本与JDK版本

官网: github.com/spring-proj…

  • Spring Framework 5.3.x: JDK 8-19 (expected)
  • Spring Framework 5.2.x: JDK 8-15
  • Spring Framework 5.1.x: JDK 8-12
  • Spring Framework 5.0.x: JDK 8-10
  • Spring Framework 4.3.x: JDK 6-8

我们在 JDK 的长期支持 (LTS) 版本上全面测试和支持 Spring,即当前的 JDK 8 和 JDK 11,很快就会支持 JDK 17(将于 2021 年末发布)。此外,我们会尽最大努力支持中间版本,例如 JDK 9/10/12/13/14/15/16/18,这意味着我们会接受错误报告并将尝试在技术上尽可能解决这些问题但不会提供任何服务水平保证。

新特性概述

官网:www.oracle.com/java/techno…

对于新特性,我们应该从哪几个角度学习新特性呢?

  • 语法层面:
    • 比如JDK5中的自动拆箱、自动装箱
    • 比如JDK8中的lambda表达式
    • 比如JDK12中的switch
  • API层面:
    • 新的API
      • 比如JDK8中的Stream、Optional、新的日期时间
    • 过时的API
      • 比如JDK9中Class类中public T newInstance()
  • JVM
    • 比如JVM优化
    • 比如垃圾回收器

语法

Sealed Classes密封类

  • 密封类和接口限制哪些其他类或接口可以扩展或实现它们。
  • 密封类JDK 15 中作为预览功能提供,并在JDK 16 中作为预览功能进行了改进。
  • 现在在 JDK 17 中,密封类被最终确定,与 JDK 16 没有任何变化。
  • 简单示例:
public sealed interface Celestial 
    permits Planet, Star, Comet { ... }

public sealed class Root { ... 
    final class A extends Root { ... }
    final class B extends Root { ... }
    final class C extends Root { ... }
}

Pattern Matching(模式匹配) for switch(==预览版==)

  • 模式匹配为JDK 16中的确定的语法
if (obj instanceof String s) {
   // 直接使用 s拼接字符串
   s += "heihei"; 
} else if (obj instanceof Integer i){
   // 直接使用i进行整型逻辑运算
   i += 1;
}
  • JDK 17中将模式匹配 应用于switch
static void typeTester(Object o) {
    switch (o) {
        case null     -> System.out.println("null");
        case String s -> System.out.println("String");
        case Color c  -> System.out.println("Color with " + Color.values().length + " values");
        case Point p  -> System.out.println("Record class: " + p.toString());
        case int[] ia -> System.out.println("Array of ints of length" + ia.length);
        default       -> System.out.println("Something else");
    }
}

API

core-libs/java.lang

  • 引入了新的系统属性 native.encoding。此系统属性提供底层主机环境的字符编码名称。例如,通常它在 Linux 和 macOS 平台中使用 UTF-8,在 Windows (en-US) 中使用 Cp1252。

core-libs/java.net

  • DatagramSocket 可直接用于加入多播组,无需使用MulticastSocket

core-libs/java.util

  • 新的接口java.util.RandomGenerator ,它为所有现有的和新的PRNG( 伪随机数生成器) 提供统一的 API。
    • 使在应用程序中交替使用各种 PRNG 算法变得更容易。
    • 通过提供 PRNG 对象流更好地支持基于流的编程。
    • 消除现有 PRNG 类中的代码重复。
    • 小心保留类 java.util.Random 的现有行为
  • java.util.HexFormat 十六进制的格式化和解析

core-libs/java.util:collections

  • 优化TreeMap.computeIfAbsent方法 错误处理值为null的问题

core-libs/java.time

  • 引入新的接口java.time.InstantSource,该接口是 java.time.Clock 的抽象,只关注当前时刻,不涉及时区。

core-libs/java.io:serialization

  • 现在可以使用 JDK Flight Recorder (JFR) 监视对象的反序列化
  • 实现特定于上下文的反序列化过滤器

JVM

hotspot/compiler

  • 移除实验性 AOT 和 JIT 编译器
    • HotSpot VM 中的 AOT Compiler 相关代码已被删除。

hotspot/runtime

  • 统一日志支持异步日志刷新
    • 为了避免使用统一日志记录的线程中出现不希望的延迟,用户现在可以请求统一日志记录系统在异步模式下运行。这可以通过传递命令行选项-Xlog:async来完成。在异步日志记录模式下,日志站点将所有日志记录消息入队到缓冲区。独立线程负责将它们刷新到相应的输出。中间缓冲区是有界的。缓冲区耗尽时,入队消息将被丢弃。用户可以使用命令行选项-XX:AsyncLogBufferSize=.来控制中间缓冲区的大小。

hotspot/gc

  • Parallel GC 默认启用自适应并行引用处理,用于处理 java.lang.ref.Reference 实例的最佳线程数。
    • 选项 -XX:ParallelRefProcEnabled 现在默认为 true(启用)
    • 在有多个线程可用于垃圾收集的机器上,这一变化显着改善了垃圾收集暂停的这一阶段。
    • 如果您遇到垃圾收集暂停增加的情况,您可以通过在命令行上指定 -XX:-ParallelRefProcEnabled 来恢复到原始行为。
    • 可以使用实验选项 -XX:ReferencesPerThread(默认值:1000)调整 java.lang.ref.Reference

下期预告

下期我们将一起学习探讨switch模式匹配