【Java】Java 17 新特性概览

这篇具有很好参考价值的文章主要介绍了【Java】Java 17 新特性概览。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. Java 17 简介

Java 17 于 2021年09月14日 正式发布,且为长期支持版本(Long-Term-Support - LTS)。

Spring 6.x 和 Spring Boot 3.x 最低支持的 Java 17,这里敲黑板:Java 17 将是继 Java 8 以来最重要的长期支持版本

下面为 Oracle Java SE 产品的一些关键产品日期示例(Oracle Java SE Product Releases):

java17,Java,java,python,开发语言

2. Java 17 新特性

类型推断 - 新的 var 关键字

从 Java 10 开始,引入了局部变量类型推断(Local Variable Type Inference)功能,它可以让我们使用关键字 var 声明局部变量(而不是实际类型),而由编译器根据变量初始化的值自动推断出类型。

// Java 8 传统变量声明方法
String str = "pointer";

// Java 10 使用类型推断的变量声明方法
var str = "pointer";

Java 11 允许在 lambda 表达式中使用 var 进行参数声明:

public class VarInLambdaExample {
    public static void main(String[] args) {
        IntStream.of(1, 2, 3, 5, 6, 7)
            .filter((var i) -> i % 2 == 0)
            .forEach(System.out::println);
    }
}

垃圾回收器改进

从 Java 9 开始,G1默认的垃圾收集器。与 Parallel GC 相比,它减少了暂停时间,尽管它的总体吞吐量可能较低。G1 的更新包括将未使用的已提交内存返回给操作系统的能力(JEP 346)。

ZGC 垃圾收集器已在 Java 11 中引入,并已在 Java 15 (JEP 377) 中达到产品状态。它旨在进一步减少停顿。从 Java 13 开始,它也可以将未使用的已提交内存返回给操作系统 (JEP 351)。

JDK 14 中引入了 Shenandoah GC,并在 Java 15 ( JEP 379) 中达到了产品状态。它旨在保持低暂停时间并独立于堆大小。

在 Java 8 中如果您没有手动更改 GC,您仍然使用 Parallel GC。简单地切换到 Java 17 可能会使您的应用程序运行得更快,并具有更一致的方法运行时间。切换到 ZGC 或 Shenandoah 可能会得到更好的结果。

最后,No-Op Garbage Collector(JEP 318),尽管它是一个实验性功能。这个垃圾收集器实际上不做任何工作,因此允许您精确测量应用程序的内存使用情况。如果您想保持尽可能低的内存操作吞吐量,则很有用。

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

JDK 17 之前,我们可以借助 Random、ThreadLocalRandom 和SplittableRandom 来生成随机数。不过,这 3 个类都各有缺陷,且缺少常见的伪随机算法支持。

Java 17 为伪随机数生成器 (PRNG) 提供新的接口类型和实现,包括可跳转的 PRNG 和另一类可拆分的 PRNG 算法 (LXM)。

PRNGopen in new window 用来生成接近于绝对随机数序列的数字序列。一般来说,PRNG 会依赖于一个初始值,也称为种子,来生成对应的伪随机数序列。只要种子确定了,PRNG 所生成的随机数就是完全确定的,因此其生成的随机数序列并不是真正随机的。

(1)提供了一个新接口 RandomGenerator

它为所有现有的和新的 PRNG 提供了一个统一的 API。 RandomGenerators 提供名为 ints、longs、doubles、nextBoolean、nextInt、nextLong、nextDouble 和 nextFloat 的方法,以及它们当前的所有参数的变化。从而更容易在应用程序中互换使用各种 PRNG 算法。例如:

public class RandomTest {

    public static void main(String[] args) {
        testRandomGenerator(new Random());
        testRandomGenerator(new SplittableRandom());
        testRandomGenerator(ThreadLocalRandom.current());
    }

    static void testRandomGenerator(RandomGenerator randomGenerator) {
        IntStream ints = randomGenerator.ints(50, 0, 10);
        int[] randoms = ints.toArray();
        for (int i : randoms) {
            System.out.println(i);
        }
        System.out.println("random count = " + randoms.length);
    }
}

(2)提供了一个新类 RandomGeneratorFactory

它用于定位和构造 RandomGenerator 实现的实例:

public class RandomTest {

    public static void main(String[] args) {
        testRandomGeneratorFactory("Random");
        testRandomGeneratorFactory("L128X128MixRandom");
        testRandomGeneratorFactory("Xoshiro256PlusPlus");
    }

    static void testRandomGeneratorFactory(String randomGeneratorName) {
        RandomGeneratorFactory<RandomGenerator> factory = RandomGeneratorFactory.of(randomGeneratorName);
        // 使用时间戳作为随机数种子
        RandomGenerator randomGenerator = factory.create(System.currentTimeMillis());

        // 生成随机数
        val nextInt = randomGenerator.nextInt(10);
        System.out.println(nextInt);
    }
}

上述方法还支持如下LXM 系列 PRNG 算法:

  • L32X64MixRandom
  • L32X64StarStarRandom
  • L64X128MixRandom
  • L64X128StarStarRandom
  • L64X256MixRandom
  • L64X1024MixRandom
  • L128X128MixRandom
  • L128X256MixRandom
  • L128X1024MixRandom

以及广泛使用的 PRNG 算法:

  • Xoshiro256PlusPlus

  • Xoroshiro128PlusPlus

(3)提供了四个新的专用 RandomGenerator 接口

  • SplittableRandomGenerator 扩展了 RandomGenerator 并且还提供名为 split 和 splits 的方法。 可拆分性允许用户从现有的 RandomGenerator 生成一个新的 RandomGenerator,这通常会产生统计上独立的结果。

  • JumpableRandomGenerator 扩展了RandomGenerator 并且还提供名为 jump 和 jumps 的方法。 可跳跃性允许用户跳到中等数量的抽签。

  • LeapableRandomGenerator 扩展了 RandomGenerator 并且还提供方法名为leap和leaps的方法。 可跳跃性允许用户跳过大量的抽签。

  • ArbitrarilyJumpableRandomGenerator 扩展了 LeapableRandomGenerator 并且还提供了jump 和 jumps 的方法额外的变体,允许指定任意跳跃距离。

JEP 356: Enhanced Pseudo-Random Number Generators

JEP 398 删除弃用的 Applet API

Applet API 在 Java 17 进行删除。

Applet API 用于编写在 Web 浏览器端运行的 Java 小程序, 在 Java 9 时被标记弃用,但没有删除。

JEP 398: Deprecate the Applet API for Removal

JEP 406 - switch 表达式增强

Java 16 中,JEP 394 扩展了 instanceof 操作符以获取类型模式并执行类型匹配。这种适度的扩展可以简化熟悉的 instanceof-and-cast 习惯用法:

// Old code
if (o instanceof String) {
    String s = (String)o;
    ... use s ...
}

// New code
if (o instanceof String s) {
    ... use s ...
}

Java 17 中对 switch 表达式进行了增强,其中包括对 switch 表达式的模式匹配进行了优化。这些改进可以让开发人员更方便地使用 switch 表达式来进行条件判断和分支控制。

// Old code
static String formatter(Object o) {
    String formatted = "unknown";
    if (o instanceof Integer i) {
        formatted = String.format("int %d", i);
    } else if (o instanceof Long l) {
        formatted = String.format("long %d", l);
    } else if (o instanceof Double d) {
        formatted = String.format("double %f", d);
    } else if (o instanceof String s) {
        formatted = String.format("String %s", s);
    }
    return formatted;
}

// New code
static String formatterPatternSwitch(Object o) {
    return switch (o) {
        case Integer i -> String.format("int %d", i);
        case Long l    -> String.format("long %d", l);
        case Double d  -> String.format("double %f", d);
        case String s  -> String.format("String %s", s);
        default        -> o.toString();
    };
}

对于 null 值的判断也进行了优化:

// Old code
static void testFooBar(String s) {
    if (s == null) {
        System.out.println("oops!");
        return;
    }
    switch (s) {
        case "Foo", "Bar" -> System.out.println("Great");
        default           -> System.out.println("Ok");
    }
}

// New code
static void testFooBar(String s) {
    switch (s) {
        case null         -> System.out.println("Oops");
        case "Foo", "Bar" -> System.out.println("Great");
        default           -> System.out.println("Ok");
    }
}

JEP 406: Pattern Matching for switch (Preview)

JEP 407 - 删除远程方法调用激活机制

删除远程方法调用 (RMI) 激活机制,同时保留 RMI 的其余部分。RMI 激活机制已过时且不再使用。

JEP 407: Remove RMI Activation

JEP 409 - 密封类(Sealed Classes)

密封类(Sealed Classes)由 JEP 360 提出,并作为预览功能在 JDK 15 中提供。它们由 JEP 397 再次提出并进行了改进,并作为预览功能在 JDK 16 中提供 。此 JEP 建议在 JDK 17 中最终确定密封类,与 JDK 16 相比没有任何更改。

没有密封类之前,在 Java 中如果想让一个类不能被继承和修改,我们可以使用 final 关键字对类进行修饰。不过,这种方式不太灵活,直接把一个类的继承和修改渠道给堵死了。

密封类可以对继承或者实现它们的类进行限制,这样这个类就只能被指定的类继承

// 抽象类 Shape 只允许 Circle 和 Circle 继承。
public sealed class Shape permits Circle, Circle {
    // Shape 类的定义
}

public final class Circle extends Shape {
    // Circle 类的定义
}

public final class Rectangle extends Shape {
    // Rectangle 类的定义
}

另外,任何扩展密封类的类本身都必须声明为 sealednon-sealedfinal

public final class Circle extends Shape {
}

public non-sealed class Rectangle extends Shape {
}

JEP 409: Sealed Classes

JEP 410 - 删除实验性的 AOT 和 JIT 编译器

在 Java 9 的 JEP 295 引入了实验性的提前 (AOT) 编译器,在启动虚拟机之前将 Java 类编译为本机代码。

在 Java 17,删除实验性的提前 (AOT) 和即时 (JIT) 编译器,因为该编译器自推出以来很少使用,维护它所需的工作量很大。保留实验性的 Java 级 JVM 编译器接口 (JVMCI),以便开发人员可以继续使用外部构建的编译器版本进行 JIT 编译。

JEP 410: Remove the Experimental AOT and JIT Compiler

JEP 411 - 删除弃用的安全管理器

安全管理器可追溯到 Java 1.0,多年来,它一直不是保护客户端 Java 代码的主要方法,也很少用于保护服务器端代码。为了推动 Java 向前发展,Java 17 删除了弃用的安全管理器。

JEP 411: Deprecate the Security Manager for Removal

JEP 412 - 外部函数和内存 API(孵化)

Java 程序可以通过该 API 与 Java 运行时之外的代码和数据进行互操作。通过高效地调用外部函数(即 JVM 之外的代码)和安全地访问外部内存(即不受 JVM 管理的内存),该 API 使 Java 程序能够调用本机库并处理本机数据,而不会像 JNI 那样危险和脆弱。

下面是 FFM API 使用示例,这段代码获取了 C 库函数的 radixsort 方法句柄,然后使用它对 Java 数组中的四个字符串进行排序。

// 1. 在C库路径上查找外部函数
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle radixSort = linker.downcallHandle(
                             stdlib.lookup("radixsort"), ...);
// 2. 分配堆上内存以存储四个字符串
String[] javaStrings   = { "mouse", "cat", "dog", "car" };
// 3. 分配堆外内存以存储四个指针
SegmentAllocator allocator = implicitAllocator();
MemorySegment offHeap  = allocator.allocateArray(ValueLayout.ADDRESS, javaStrings.length);
// 4. 将字符串从堆上复制到堆外
for (int i = 0; i < javaStrings.length; i++) {
    // 在堆外分配一个字符串,然后存储指向它的指针
    MemorySegment cString = allocator.allocateUtf8String(javaStrings[i]);
    offHeap.setAtIndex(ValueLayout.ADDRESS, i, cString);
}
// 5. 通过调用外部函数对堆外数据进行排序
radixSort.invoke(offHeap, javaStrings.length, MemoryAddress.NULL, '\0');
// 6. 将(重新排序的)字符串从堆外复制到堆上
for (int i = 0; i < javaStrings.length; i++) {
    MemoryAddress cStringPtr = offHeap.getAtIndex(ValueLayout.ADDRESS, i);
    javaStrings[i] = cStringPtr.getUtf8String(0);
}
assert Arrays.equals(javaStrings, new String[] {"car", "cat", "dog", "mouse"});  // true

JEP 412: Foreign Function & Memory API (Incubator)

JEP 414 - 向量(Vector) API(第二次孵化)

Vector API 最初在 Java 16 孵化并集成,在 Java 17 中进行第二次孵化。这个特性可以让开发人员更方便地使用向量操作来进行数据处理。Vector API 可以提供更高的并行性和更好的性能,从而加速数据处理过程。

// 创建一个 Vector
Vector<Float> v = Vector.of(1.0f, 2.0f, 3.0f, 4.0f);

// 对 Vector 中的元素进行操作
Vector<Float> result = v.map(x -> x * 2).add(Vector.of(1.0f, 1.0f, 1.0f, 1.0f));

// 输出结果
System.out.println(result);

JEP 414: Vector API (Second Incubator)

更多新特性请参考:

JDK 17 – New Features in Java 17

https://openjdk.org/projects/jdk/17/

3. Java 17 升级实战

解决GC毛刺问题——转转搜索推荐服务JDK17升级实践文章来源地址https://www.toymoban.com/news/detail-751654.html

到了这里,关于【Java】Java 17 新特性概览的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java17 新特性和改进

    Java 17 是 Java 编程语言和标准库的最新版本,是一个非常重要的更新。作为 Java 9 后的第 8 个长期支持版本(LTS),Java 17 带来了一系列有趣的新特性、改进和优化,包括 Sealed Class、Pattern Matching for instanceof、升级的垃圾回收器、ZGC 性能优化等等。在本篇文章中,我们将介绍

    2024年02月01日
    浏览(92)
  • [Java]JDK17新特性

    目录   一、JDK新特性 1.1Java Record 1.1.1Record的使用 1.1.2Instance Methods 1.1.3静态方法 Static Method 1.1.4Record构造方法 1.1.5Record与Lombok 1.1.6Record实现接口 1.1.7Local Record 1.1.8嵌套Record 1.1.9instanceof判断Record类型 1.1.10总结 1.2Switch 1.2.1箭头表达式 1.2.2yield返回值 1.2.3Java Record 1.3Text Block 1.3.1认识

    2024年02月07日
    浏览(49)
  • JAVA8~17新特性

    目录 一、前言 二、JAVA8 Lambda表达式 Stream API 创建方式 中间操作 终止操作 Optional类 三、JAVA9 模块机制 JShell交互式编程   接口 新增集合工厂方法 四、JAVA10 局部变量类型判断 五、JAVA11 Lambda表达式补充 String方法的补充 全新的HttpClient 使用 六、JAVA12-16 新的switch语法 文本块 新

    2024年02月15日
    浏览(43)
  • Java 17 版本的新特性

    Java 17 是2021年9月发布的最新版本,其中包含了很多新特性和改进,这些新特性和改进将进一步提高 Java 语言的性能和可用性。在这篇博客中,我们将介绍 Java 17 中的一些重要新特性。 摘要: Java 17是Java编程语言的一个新版本,它引入了一些新的特性和改进,使得Java编程更加

    2024年02月09日
    浏览(46)
  • Java 17新特性讲解与代码实例

    Java 17是Java SE 17的开源参考实现,于2021年9月14日正式发布,是Java 11以来的又一个长期支持(LTS)版本。Java 17中有一些新的特性和改进,本文将对它们进行简要的介绍和示例。 密封类 密封类和接口限制了哪些其他类或接口可以扩展或实现它们,增强了封装性和可维护性。密封

    2024年02月16日
    浏览(37)
  • 拥抱变化,面向Java17,Java8-18全系列特性详解

    文章目录: Java 8 新特性 Java 9 新特性 Java 10 新特性 Java 11 新特性 Java 12 新特性 Java 13 新特性 Java 14 新特性 Java 15 新特性 Java 16 新特性 Java 17 新特性 Java 18 新特性 💡 文章较长,建议点赞、收藏、评论后慢慢看,合理利用 “ 只看目录功能 ” 当我们大部分Javaer还沉浸在Java 8 的

    2024年01月16日
    浏览(42)
  • 走近JDK 17,探索最新Java特性,拥抱未来编程!

    大家好,我是小米,一个热爱技术分享的程序员。今天,我将为大家介绍一下JDK 17的新特性。JDK 17是Java开发工具包的一个重要版本,其中包含了许多令人激动的新功能和改进。在这篇文章中,我将详细介绍JDK 17中的各项特性,并说明它们在电商应用场景中的应用。 密封类(

    2024年02月11日
    浏览(43)
  • Java 21:最新特性、性能改进和语言发展

    🎉欢迎来到Java学习路线专栏~Java 21:最新特性、性能改进和语言发展 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:Java学习路线 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和水平有

    2024年02月05日
    浏览(40)
  • Java/Python/Go不同开发语言在进程、线程和协程的设计差异

    在多线程项目开发时,最常用、最常遇到的问题是 1,线程、协程安全 2,线程、协程间的通信和控制 本文主要探讨不同开发语言go、java、python在进程、线程和协程上的设计和开发方式的异同。 进程 进程是 操作系统进行资源分配的基本单位,每个进程都有自己的独立内存空

    2024年01月23日
    浏览(50)
  • 【Java开发】设计模式 17:中介者模式

    中介者模式是一种行为设计模式,指用一个中介对象来封装一系列的对象交互。 中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。在这个模式中,中介者负责协调各个对象间的通信,使其流程更加清晰简单。 📌  场景 中介者

    2023年04月22日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包