JDK17常用新特性

时间:2024-10-14 10:10:42

目前国内大部分开发人员都是在使用jdk8,甚至是jdk6,但是随着jdk的更新迭代,jdk8我觉得可能就会慢慢的淡出舞台,随着目前主流框架最新版推出明确说明了不再支持jdk8,也促使我不得不抓紧学习了解一波jdk17的新特性,以备不时之需。
所以屏幕前的小伙伴不要觉得这会不会太过遥远,那我这里找一些数据,大家可以参考一下,自己根据需求看看是否自己所在的行业或者是领域有没有在变化
在这里插入图片描述

2023年newRelic统计
另外springframwork6.x,Jenkins3.5,kafka最新版,SpringBoot3.x也停止对jdk8的支持
当然我这里列出这些数据也只是想提醒我们这些技术人,不管用什么,都不要停下脚步。
这里我对jdk17的一些常用的特性在这里学习整理了一下,以便后面需要的时候可以查看回忆

一、Switch增强

以前jdk8的版本,我们写switch是不是发现会很长当我们的条件比较多的时候,而且每一个case后面需要跟上break或者continue,在jdk17里会变得很清爽。
下面我们来看下jdk8和jdk17里switch的写法区别:

public class Demo_Switch {

        public static void main(String[] args) {
                String name = "张三";
                String alias17 = switch (name) {
                case "张三", "李四" -> "王五";
                default -> throw new IllegalArgumentException("Unexpected value: " + name);
                };
                
                System.out.println("jdk17写法输出 alias:" + alias17);
                
                alias17 = switch (name) {
                case "张三" -> {
                        System.out.println("内部处理逻辑...");
                        yield "王五";
                }
                default -> {
                        throw new IllegalArgumentException("Unexpected value: " + name);
                }
                };
                System.out.println("jdk17写法输出 alias:" + alias17);
                
                String alias8 = "";
                switch(name) {
                case "张三":
                case "李四":
                        alias8 = "lisi";
                        System.out.println("jdk8写法输出 alias:" + alias8);
                        break;
                default:
                        throw new IllegalArgumentException("Unexpected value: " + name);
                }
                
        }

}

可以看到上面jdk8的写法需要10行,而jdk17的写法只需要5行代码。

  1. 可以发现匹配多个条件只需要在case后面用逗号分割多个条件即可;
  2. 另外支持采用->的形式作为返回值直接赋值给变量;
  3. 另外移除了break。
  4. 支持采用代码块的形式作为case匹配的执行逻辑编写

二、String字符串拼接增强

jdk17以前我们对字符串的拼接往往好写好多的+,现在jdk17支持使用"""作为字符块来对字符串拼接增强,另外jdk17增加了转义符用于对字符串内需要换行或者空格的支持

  • \:空格
  • \n:换行
public class Demo_String {

        public static void main(String[] args) {
                String sql = 
                        """
                        SELECT 
                                ID,
                                NAME,
                                AGE
                        FROM T_STUDENT
                        WHERE NAME = '%s'
                        """;
                System.out.println(String.format(sql, "张三"));
        }

}

三、模式匹配instanceof

3.1、模式匹配的原理剖析

  1. 模式匹配 for instanceof 是 Java 17 中引入的一项新特性,它允许在进行instanceof类型检查时,同时进行变量的类型转换,从而使代码更加简洁和直观。
  2. 模式匹配的原理是通过在instanceof操作符后面使用模式来进行类型判断和变量赋值。如果类型判断成功,变量将被自动转换为对应的类型,从而可以直接进行操作,避免了繁琐的类型转换代码。
    下面我们来看下具体是怎么使用的:
    使用模式匹配 for instanceof 可以将传统的instanceof类型检查和类型转换代码简化为一个更加简洁的表达式。例如,
  • 在 Java 17 之前,我们可能会这样写代码
public class Demo_Instanceof {

        public static void main(String[] args) {
                Object o = new String("哈哈哈");
                if (o instanceof String) {
                        String s = (String) o;
                        System.out.println(s);
                }
        }
}
  • 在 Java 17 中,我们可以使用模式匹配来简化这段代码:
    Object obj = new String("哈哈哈");
    if (obj instanceof String str) {
        System.out.println(str.length());
    }

四、密封类Sealed Class

4.1、密封类的定义与作用

密封类是 Java 17 中引入的一个新特性,用于限制类的继承结构。通过密封类,开发者可以明确指定哪些类可以继承自一个基类,从而增强了类型系统的安全性和可维护性。
密封类的主要作用是防止意外的类继承,确保类的设计意图得到正确的实现。它可以帮助开发者更好地控制代码的结构和行为,减少潜在的错误和风险。

4.2、密封类及子类的定义方式

  • 要定义一个密封类,需要使用sealed关键字修饰类声明,并指定允许继承的子类列表。例如:
public sealed class Demo_SealedClass permits Demo_SubSealedClass1, Demo_SubSealedClass2 {

        public void baseMethod() {
                System.out.println("我是密封父类");
        }
        
}
  • 子类需要使用non-sealed关键字(如果不是最终类)或final关键字来表明其继承状态。例如:
public non-sealed class Demo_SubSealedClass1 extends Demo_SealedClass {

        @Override
        public void baseMethod() {
                System.out.println("我是密封子类1");
        }

}

public final class Demo_SubSealedClass2 extends Demo_SealedClass{

        @Override
        public void baseMethod() {
                System.out.println("我是密封子类2");
        }

}

实际应用场景与优势分析

  1. 当一个类的设计不希望被随意继承或扩展时,可以使用密封类来限制继承结构。
  2. 对于一些框架或库的核心类,为了保证其稳定性和安全性,可以使用密封类来控制类的继承。
    注意:
    1、密封类的父类和子类都必须要在同一个包下
    2、子类必须直接继承密封父类

五、新的垃圾回收器ZGC

5.1、新垃圾回收器的特点与优势

JDK 17 中引入了一种新的垃圾回收器,旨在提高垃圾回收的效率和性能,减少垃圾回收对应用程序性能的影响。
新的垃圾回收器采用了一些先进的技术和算法,如并发标记清除、增量更新等,能够更快速地完成垃圾回收操作,同时减少了垃圾回收过程中的暂停时间,提高了应用程序的响应性和吞吐量。

5.2、性能测试与对比分析

为了评估新垃圾回收器的性能,我们可以进行一些性能测试,并将其与传统的垃圾回收器进行对比分析。例如,我们可以使用一些基准测试工具来测试应用程序在不同垃圾回收器下的性能指标,如吞吐量、暂停时间、内存占用等。
通过对比分析,我们可以发现新垃圾回收器在大多数情况下都能够提供更好的性能表现,特别是在处理大规模数据和高并发场景下,新垃圾回收器的优势更加明显。

    java -XX:+UseZGC MyApplication

可以使用上述的jvm参数配置使得ZGC回收机制生效,垃圾回收机制是JVM不可避免的一种机制,目的就是防止内存溢出,jdk8及以前是通过频繁的触发堆内存的回收机制去释放内存,每一次回收都会触发STW停顿,这就造成了性能的损耗,而解决的办法就是降低停顿或者提高堆内存。jdk17可以将堆内存设置的很大,另外就是可以通过配置ZGC提高内存回收。