返回顶部
首页 > 资讯 > 后端开发 > JAVA >Java 17新特性讲解与代码实例
  • 762
分享到

Java 17新特性讲解与代码实例

java开发语言java17 2023-09-07 16:09:28 762人浏览 安东尼
摘要

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

Java 17是Java SE 17的开源参考实现,于2021年9月14日正式发布,是Java 11以来的又一个长期支持(LTS)版本。Java 17中有一些新的特性和改进,本文将对它们进行简要的介绍和示例。

密封类

密封类和接口限制了哪些其他类或接口可以扩展或实现它们,增强了封装性和可维护性。密封类由JEP 360并在jdk 15中作为预览功能交付。它们再次被提出,并进行了改进,由JEP 397并在JDK 16中作为预览功能提供。现在,在JDK 17中,密封类正在最终确定,与JDK 16没有任何更改。

要定义一个密封类或接口,需要使用sealed修饰符,并且在声明中指定允许扩展或实现它的其他类或接口。这些类或接口被称为子类或子接口。子类或子接口可以使用final修饰符来表示它们不能被进一步扩展或实现,或者使用sealed修饰符来表示它们也是密封的,并且需要指定它们的子类或子接口,或者使用non-sealed修饰符来表示它们不是密封的,并且可以被任意的类或接口扩展或实现。

例如,我们可以定义一个密封的形状接口Shape,并且指定它只能被Circle、Rectangle和Triangle这三个类实现:

public sealed interface Shape permits Circle, Rectangle, Triangle {    double area();}

然后,我们可以定义这三个类,并且分别使用finalsealednon-sealed修饰符:

public final class Circle implements Shape {    private final double radius;    public Circle(double radius) {        this.radius = radius;    }    public double area() {        return Math.PI * radius * radius;    }}public sealed class Rectangle implements Shape permits Square {    private final double length;    private final double width;    public Rectangle(double length, double width) {        this.length = length;        this.width = width;    }    public double area() {        return length * width;    }}public non-sealed class Triangle implements Shape {    private final double base;    private final double height;    public Triangle(double base, double height) {        this.base = base;        this.height = height;    }    public double area() {        return base * height / 2;    }}

注意,Square是Rectangle的子类,并且也是密封的:

public final class Square extends Rectangle {    public Square(double side) {        super(side, side);    }}

这样,我们就可以保证Shape接口只能被这四个类实现,而不会有其他的可能性。我们也可以使用模式匹配来对不同的形状进行操作,例如:

public static void printArea(Shape shape) {    if (shape instanceof Circle c) {        System.out.println("The area of the circle is " + c.area());    } else if (shape instanceof Rectangle r) {        System.out.println("The area of the rectangle is " + r.area());    } else if (shape instanceof Triangle t) {        System.out.println("The area of the triangle is " + t.area());    }}

switch表达式

switch表达式允许switch有返回值,并且可以直接作为结果赋值给一个变量,简化了多分支的逻辑。switch表达式由JEP 325并在JDK 12中作为预览功能交付。它们再次被提出,并进行了改进,由JEP 354并在JDK 13中作为预览功能提供。它们再次被提出,并进行了改进,由JEP 361并在JDK 14中作为预览功能提供。现在,在JDK 17中,switch表达式正在最终确定,与JDK 14没有任何更改。

要定义一个switch表达式,需要使用->符号来表示每个分支的结果,并且在表达式的末尾加上一个分号。例如,我们可以定义一个根据月份返回季节的switch表达式:

public static String getSeason(int month) {    return switch (month) {        case 12, 1, 2 -> "Winter";        case 3, 4, 5 -> "Spring";        case 6, 7, 8 -> "Summer";        case 9, 10, 11 -> "Autumn";        default -> "Unknown";    };}

注意,我们可以使用逗号来分隔多个匹配值,也可以使用default来表示其他情况。我们也可以使用yield关键字来返回一个值,这在需要在返回之前进行一些操作的情况下很有用,例如:

public static String getSeason(int month) {    return switch (month) {        case 12, 1, 2 -> {            System.out.println("It's cold!");            yield "Winter";        }        case 3, 4, 5 -> {            System.out.println("It's warm!");            yield "Spring";        }        case 6, 7, 8 -> {            System.out.println("It's hot!");            yield "Summer";        }        case 9, 10, 11 -> {            System.out.println("It's cool!");            yield "Autumn";        }        default -> {            System.out.println("It's unknown!");            yield "Unknown";        }    };}

文本块

文本块允许使用三个双引号来定义一个多行的字符串,避免了转义和拼接的麻烦。文本块由JEP

355并在JDK 13中作为预览功能交付。它们再次被提出,并进行了改进,由JEP 368并在JDK 14中作为预览功能提供。它们再次被提出,并进行了改进,由JEP 378并在JDK 15中作为预览功能提供。现在,在JDK 17中,文本块正在最终确定,与JDK 15没有任何更改。

要定义一个文本块,需要使用三个双引号"""来开始和结束,并且结束的三个双引号不能和开始的在同一行。例如,我们可以定义一个包含JSON数据的文本块:

public static String getjson() {    return """    {        "name": "Java",        "version": 17,        "features": [            "sealed classes",            "switch expressions",            "text blocks"        ]    }    """;}

注意,文本块中的换行符会被保留,而不需要使用\n来表示。我们也可以使用\来表示忽略换行符,或者使用\s来表示一个空格。例如:

public static String getGreeting() {    return """    Hello,\    World!    """;}public static String getPoem() {    return """    Twinkle, twinkle, little star,\s    How I wonder what you are.\s    Up above the world so high,\s    Like a diamond in the sky.    """;}

模式匹配

模式匹配允许在instanceof和switch中使用模式来测试表达式的类型和结构,提高了代码的可读性和灵活性。模式匹配由JEP 305并在JDK 14中作为预览功能交付。它们再次被提出,并进行了改进,由JEP 375并在JDK 15中作为预览功能提供。它们再次被提出,并进行了改进,由JEP 394并在JDK 16中作为预览功能提供。现在,在JDK 17中,模式匹配正在最终确定,与JDK 16没有任何更改。

要使用模式匹配,需要使用instanceofswitch关键字,并且在测试的类型后面加上一个变量名,用于绑定匹配的值。例如,我们可以使用模式匹配来判断一个对象是否是字符串,并且获取它的长度:

public static void printLength(Object obj) {    if (obj instanceof String s) {        System.out.println("The length of the string is " + s.length());    } else {        System.out.println("The object is not a string");    }}

注意,我们不需要再进行强制类型转换,因为变量s已经被绑定为字符串类型。我们也可以使用模式匹配来判断一个对象是否是密封类的子类,并且获取它的属性:

public static void printShape(Shape shape) {    switch (shape) {        case Circle c -> System.out.println("The radius of the circle is " + c.radius());        case Rectangle r -> System.out.println("The area of the rectangle is " + r.area());        case Triangle t -> System.out.println("The base of the triangle is " + t.base());        default -> System.out.println("Unknown shape");    }}

注意,我们不需要再进行类型检查或者类型转换,因为变量crt已经被绑定为相应的类型。

增强型伪随机数生成器

增强型伪随机数生成器为PRNG提供了新的接口类型和实现,包括可跳转的PRNG和一类额外的可拆分PRNG算法(LXM)。增强型伪随机数生成器由JEP 356并在JDK 17中作为正式功能提供。

要使用增强型伪随机数生成器,需要使用java.util.random包中的新的接口和类。例如,我们可以使用RandomGenerator接口来获取一个PRNG的实例,并且使用它来生成各种类型的随机数:

public static void generateRandomNumbers() {    RandomGenerator random = RandomGenerator.getDefault();    System.out.println("A random boolean: " + random.nextBoolean());    System.out.println("A random int: " + random.nextInt());    System.out.println("A random long: " + random.nextLong());    System.out.println("A random float: " + random.nextFloat());    System.out.println("A random double: " + random.nextDouble());}

注意,RandomGenerator接口提供了很多方便的方法来生成不同范围和分布的随机数,例如nextInt(int bound)nextLong(long bound)nextGaussian()等。我们也可以使用RandomGeneratorFactory类来获取不同的PRNG算法的实例,例如:

public static void useDifferentAlGorithms() {    RandomGenerator random1 = RandomGeneratorFactory.of("L32X64MixRandom");    RandomGenerator random2 = RandomGeneratorFactory.of("L64X128MixRandom");    RandomGenerator random3 = RandomGeneratorFactory.of("L128X256MixRandom");    System.out.println("Using L32X64MixRandom: " + random1.nextInt());    System.out.println("Using L64X128MixRandom: " + random2.nextInt());    System.out.println("Using L128X256MixRandom: " + random3.nextInt());}

注意,RandomGeneratorFactory类提供了很多方法来获取或者查询不同的PRNG算法,例如of(String name)all()preferred()等。我们也可以使用JumpableRandomGenerator接口或者SplittableRandomGenerator接口来获取一个可跳转或者可拆分的PRNG实例,并且使用它们来生成不同的子生成器,例如:

public static void useJumpableOrSplittableGenerators() {    JumpableRandomGenerator jumpable = RandomGeneratorFactory.jumpable();    SplittableRandomGenerator splittable = RandomGeneratorFactory.splittable();    System.out.println("Using the original jumpable generator: " + jumpable.nextInt());    System.out.println("Using the original splittable generator: " + splittable.nextInt());    JumpableRandomGenerator jumped = jumpable.jump();    SplittableRandomGenerator splitted = splittable.split();    System.out.println("Using the jumped generator: " + jumped.nextInt());    System.out.println("Using the splitted generator: " + splitted.nextInt());}

注意,JumpableRandomGenerator接口和SplittableRandomGenerator接口都继承自RandomGenerator接口,并且提供了额外的方法来生成子生成器,例如jump()split()等。这些子生成器可以用于并行计算或者其他场景。

新的MacOS渲染管道

新的macOS渲染管道使用Apple Metal加速渲染api来替代被Apple弃用的OpenGL API。新的macOS渲染管道由JEP 382并在JDK 17中作为正式功能提供。

要使用新的macOS渲染管道,需要在运行Java程序时设置系统属性:

-Dsun.java2d.metal=true

这样,Java 2D API和Swing API用于渲染的Java 2D API就可以使用Metal API来加速渲染。这对于Java程序是透明的,因为这是内部实现的区别,对Java API没有影响。Metal管道需要macOS 10.14.x或更高版本。在早期版本上设置它的尝试将被忽略。

来源地址:https://blog.csdn.net/caicai250/article/details/131415249

--结束END--

本文标题: Java 17新特性讲解与代码实例

本文链接: https://lsjlt.com/news/398527.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java 17新特性讲解与代码实例
    Java 17是Java SE 17的开源参考实现,于2021年9月14日正式发布,是Java 11以来的又一个长期支持(LTS)版本。Java 17中有一些新的特性和改进,本文将对它们进行简要的介绍和示例。 密封类 密封类和接口限制了哪些...
    99+
    2023-09-07
    java 开发语言 java17
  • PHP8新特性之JIT案例讲解
    PHP8 alpha1已经在昨天发布,相信关于JIT是大家最关心的,它到底怎么用,有什么要注意的,以及性能提升到底咋样? 首先,我们来看一张图: 左图是 PHP 8之前的Opcac...
    99+
    2024-04-02
  • Go1.18新特性之泛型实例代码分析
    本篇内容主要讲解“Go1.18新特性之泛型实例代码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go1.18新特性之泛型实例代码分析”吧!1. 一切从函数的形参和实参说起假设我们有个计算两数...
    99+
    2023-07-05
  • Java volatile关键字特性实例代码分析
    这篇文章主要讲解了“Java volatile关键字特性实例代码分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java volatile关键字特性实例代码分析”吧!一...
    99+
    2023-07-04
  • 深入讲解Java 9中的九个新特性
    本文主要跟大家分享了Java 9中的九个新特性,对大家具有一定的参考学习价值,下面来看看详细的介绍:一、 Java 平台级模块系统Java 9 的定义功能是一套全新的模块系统。当代码库越来越大,创建复杂,盘根错节的“意大利面条式代...
    99+
    2023-05-31
    java9 新特性 ava
  • Java新特性使用实例分析
    这篇文章主要介绍“Java新特性使用实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java新特性使用实例分析”文章能帮助大家解决问题。枚举:尽管在 JDK 5 中增加了枚举类型,但是 Cla...
    99+
    2023-06-27
  • Java8新特性StreamAPI实例详解
    目录Stream结果收集结果收集到集合中结果收集到数组中对流中的数据做聚合计算对流中数据做分组操作对流中的数据做分区操作对流中的数据做拼接并行的Stream流串行的Stream流并行...
    99+
    2022-11-13
    Java8新特性 StreamAPI Java8 StreamAPI
  • 代码讲解java的单例模式
    单例模式可以说是最常用的设计模式之一,其主要作用就是保证一个类只有一个实例,并且提供一个访问它的全局访问点,严格的控制用户的访问方式。单例模式又分为懒汉模式和饿汉模式,首先说一下饿汉模式:饿汉模式饿汉模式有点饥不择食的意思,就像一个人饿了很...
    99+
    2018-01-20
    java基础 java 单例模式
  • Java实例讲解动态代理
    JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。 CGlib动态代理:利用ASM(开源的Java字节码编辑库,操作字节...
    99+
    2024-04-02
  • Java哈希表和有序表实例代码讲解
    目录哈希表(HashMap)按值传递按址传递内存大小比较有序表(TreeMap)哈希表(HashMap) hash查询的时间复杂度是O(1) 按值传递 Character,Short...
    99+
    2023-05-15
    Java哈希表和有序表 Java哈希表 Java有序表
  • JDK19新特性使用实例详解
    目录前提新特性列表新特性使用详解Record模式Linux/RISC-V移植外部函数和内存API虚拟线程向量APIswitch匹配模式结构化并发前提 JDK19于2022-09-20...
    99+
    2024-04-02
  • Java8新特性之Collectors.joining()实例详解
    目录方法定义无参方法单个参数多个参数如果流中的数据是字符串如果流中的数据是对象总结方法定义 Java 8 流 ( stream ) 收集器 ( Collectors ) 中的&nbs...
    99+
    2023-01-12
    java8新特性collectors.joining() java8 collectors.joining()
  • Java 普通代码块静态代码块执行顺序(实例讲解)
    如下所示:class B { public B() { super(); System.out.println("构造器B"); } { System.out.println("普通的代码块B"); } static{ System...
    99+
    2023-05-31
    静态代码块 执行顺序 java
  • Java8新特性 | List多字段排序(含示例代码)
    可以利用 List 的 sort 方法进行排序,Comparator.comparing 可以指定排序字段,thenComparing 可以继续指定其他的排序字段。 默认使用正序排列,如果想倒序可...
    99+
    2023-09-13
    java 算法 开发语言
  • C语言示例代码讲解栈与队列
    目录栈栈的定义顺序栈顺序栈的定义顺序栈的初始化顺序栈的入栈顺序栈的出栈取顺序栈的栈顶元素链栈队列队列的定义队列的顺序表达与实现队列顺序存储结构假溢出循环队列循环队列的初始化循环队列的...
    99+
    2024-04-02
  • Java之map的常见用法讲解与五种循环遍历实例代码理解
    目录一、概述:二、Map集合的功能介绍三、map官方总结四、实例五、循环遍历的五种方法一、概述: 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 Map接口...
    99+
    2024-04-02
  • python代码实现备忘录案例讲解
    文件操作 TXT文件 读取txt文件 读取txt文件全部内容: def read_all(txt): ...: with open(txt,'r') as f: ...
    99+
    2024-04-02
  • php优化查询foreach代码实例讲解
    php代码优化 应避免在php foreach里面进行sql查询 以下代码示例使用了laravel的操作数据库api,eloquent orm foreach里面执行两次sql查询 ...
    99+
    2024-04-02
  • Java数据结构与算法实例讲解
    这篇文章主要讲解了“Java数据结构与算法实例讲解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java数据结构与算法实例讲解”吧! 为什么需要树这种结构数组存储方式分析:优点:通...
    99+
    2023-06-15
  • 详解Java中接口的定义与实例代码
    Java中接口的定义详解1、定义接口    使用interface来定义一个接口。接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成。定义接口的基本格式如下:[修饰符]...
    99+
    2023-05-31
    java 接口 ava
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作