当前位置: 首页 > news >正文

JDK17 新特性跟学梳理

JDK17 新特性跟学梳理

  • JDK17 背景介绍
  • 一、JDK 17对Switch语句的增强
  • 二、字符串拼接
  • 三、强制转换
  • 四、密封类Sealed Classes
  • 五、Record类
  • 六、优化空指针异常信息
  • 七、ZGC垃圾收集器
  • 八、JVM常量API
  • 九、重写Socket底层API
  • 十、JDK飞行记录事件流
  • 十一、EdDSA签名算法
  • 十二、隐藏类
  • 十三、对Value-Based类型的警告
  • 十四、统一的PRNG接口(Enhanced Pseudo-Random Number Generators)
  • 十五、特定于上下文的反序列化过滤器
  • 十五、恢复始终严格的浮点语义

JDK17 背景介绍

  • 关注版本:LTS(Long-Term Support 长期支持
  • 目前主流版本
    在这里插入图片描述
  • 主要应用
    • Spring FrameWork 6.X 要求最低JDK17版本
    • SpringBoot 3.0要求最低JDK17版本
    • Kafka 3.00表示不再支持JDK8
    • Jenkins在最新的2.357版本发表声明最低支持JDK11

一、JDK 17对Switch语句的增强

JDK 17支持多case同返回值的便捷书写,以及yield关键字返回变量返回值

代码示例:

public class Main {public static void main(String[] args) {// JDK 8switchOld();// JDK 12switchNew();// JDK 17switchNewer();}/*** 功能描述: JDK 8 的Switch语句** @param* @return void* @date 2025/7/28 22:52* @author Derrick**/public static void switchOld() {String name = "徐庶";String alias = "";switch (name) {case "周瑜":alias = "公瑾";break;case "徐庶":alias = "元直";break;case "项羽":alias = "西楚霸王";break;case "张三":case "李四":alias = "王五";break;case "小米su7":case "小米yu7":alias = "小米智能车";System.out.println("小米智能车");break;}System.out.println("JDK8 alias:" + alias);}/*** 功能描述: JDK 12 的Switch语句** @param* @return void* @date 2025/7/28 22:52* @author Derrick**/public static void switchNew() {String name = "徐庶";String alias = switch (name) {case "周瑜" -> "公瑾";case "徐庶" -> "元直";case "项羽" -> "西楚霸王";default -> throw new IllegalStateException("Unexpected value: " + name);};System.out.println("JDK17 alias:" + alias);}/*** 功能描述: JDK 17 的Switch语句** @param* @return void* @date 2025/7/28 22:57* @author Derrick**/public static void switchNewer() {String name = "小米su7";String alias = switch (name) {case "周瑜" -> "公瑾";case "徐庶" -> "元直";case "项羽" -> "西楚霸王";// JDK 17版本新特性case "张三", "李四" -> "王五";case "小米su7", "小米yu7" -> {System.out.println("小米智能车");// yield关键字作为变量的返回值yield "小米智能车";}default -> throw new IllegalStateException("Unexpected value: " + name);};System.out.println("JDK17 alias:" + alias);}
}

二、字符串拼接

JDK 17中
\是置于末尾,作用是将2行转为1行
\s是单个空白字符

package com.itheima.methods;/*** @ClassName: StringWay* @Description:* @Author: Derrick* @Date: 2025/7/28*/public class StringWay {private String oldStr = "<html>\n" +"<body>\n" +"<h1>Hello, World!</h1>\n" +"<body>\n" +"</html>\n";private String newStr = """<html><body><h1>Hello, World!</h1></body></html>""";// JDK 17中\是置于末尾,作用:将2行转为1行   \s是单个空白字符private String newerStr = """<html>\<b\sody><h1>Hello, World!</h1></body></html>""";public StringWay() {System.out.println("JDK 8" + dealWithStringOld(oldStr));System.out.println("JDK 15" + dealWithStringOld(newStr));System.out.println("JDK 17" + dealWithStringOld(newerStr));}public String dealWithStringOld(String oldStr) {return oldStr;}
}

控制台打印效果

JDK 8<html>
<body>
<h1>Hello, World!</h1>
<body>
</html>JDK 15<html><body><h1>Hello, World!</h1></body>
</html>JDK 17<html>    <b ody><h1>Hello, World!</h1></body>
</html>

三、强制转换

JDK 17可以便捷书写包装类的强制类型转换
package com.itheima.methods;/*** @ClassName: ChangeInstance* @Description:* @Author: Derrick* @Date: 2025/7/28*/public class ChangeInstance {public ChangeInstance() {oldInstance(1);newInstance("对");}/*** 功能描述: JDK 8中需要强制转换对应类型** @param* @param o* @return void* @date 2025/7/28 23:27* @author Derrick**/public void oldInstance(Object o) {if (o instanceof Integer) {Integer i = (Integer) o;System.out.println(i.intValue());} else if (o instanceof String) {String s = (String) o;System.out.println(s.charAt(0));}}/*** 功能描述: JDK 14中优化** @param* @param o* @return void* @date 2025/7/28 23:28* @author Derrick**/public void newInstance(Object o) {if (o instanceof Integer i) {System.out.println(i.intValue());} else if (o instanceof String s) {System.out.println(s.charAt(0));}}
}

打印效果如下:

1

四、密封类Sealed Classes

permits关键字,限制只有子类才能继承父类。
子类必须使用non-sealed或者final关键字,final表示不能再被子子类继承,non-sealed表示能被子子类继承。
密封类和子类必须同处于一个包下,如果不在一个包下,就会报错。
子类必须直接继承自密封类,不能间接继承,否则会报错。
密封类的好处:(1)密封类更加安全,可以限制子子类的继承 (2).密封类更加可控,减少代码复杂性,易于维护

密封类代码示例:

package com.itheima.methods;/*** @ClassName: SealedTest* @Description: permits关键字,限制只有SealedSon才能继承SealedFather类* @Author: Derrick* @Date: 2025/7/29*/public abstract sealed class SealedFather permits SealedSon {}

子类代码示例

package com.itheima.methods;/*** @ClassName: SealedSon* @Description: 子类必须使用non-sealed或者final关键字* @Author: Derrick* @Date: 2025/7/29*/public non-sealed class SealedSon extends SealedFather {
}

五、Record类

类似lombok的属性只读对象

IDEA创建class的时候选择Record
在这里插入图片描述
Record示例如下:

package com.itheima.methods;/*** @RecordName: UserRecord* @Description:* @Author: Derrick* @Date: 2025/7/29*/
public record UserRecord(Long id, String userName) {
}

编译的.class字节码文件如下:

package com.itheima.methods;public record UserRecord(Long id, String userName) {public UserRecord(Long id, String userName) {this.id = id;this.userName = userName;}public Long id() {return this.id;}public String userName() {return this.userName;}
}

Main函数

import com.itheima.methods.ChangeInstance;
import com.itheima.methods.StringWay;
import com.itheima.methods.UserRecord;public class Main {public static void main(String[] args) {// RecordUserRecord userRecordOne = new UserRecord(1L, "Lily");UserRecord userRecordTwo = new UserRecord(1L, "Lily");System.out.println("userRecordOne.name:" + userRecordOne.userName());System.out.println("userRecordOne:" + userRecordOne);System.out.println("userRecordTwo.name:" + userRecordTwo.userName());System.out.println("userRecordTwo:" + userRecordTwo);System.out.println(userRecordOne.equals(userRecordTwo));}
}

控制台打印

userRecordOne.name:Lily
userRecordOne:UserRecord[id=1, userName=Lily]
userRecordTwo.name:Lily
userRecordTwo:UserRecord[id=1, userName=Lily]
true

这里可以看到Record对象的属性值相同,就是一个对象
在这里插入图片描述

六、优化空指针异常信息

这个改动是JDK 14的,这里特别讲解一下

可以便捷查看空指针异常出自哪一句代码的哪个对象为null

代码示例

public static void main(String[] args) {// 解决空指针String str = null;int length = str.length();System.out.println("字符串长度:" + length);}

控制台打印

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "str" is nullat Main.main(Main.java:34)

可以看到JDK14针对哪个对象空指针是有说明的

七、ZGC垃圾收集器

JDK11诞生,JDK15正式使用,JDK17已经很成熟
优点:垃圾回收不卡顿(stop the world少于10ms),Java开发不用愁

在这里插入图片描述
可以看到JDK17的垃圾回收期性能最优
在这里插入图片描述
使用方式,配置如下即可,因为JDK11和JDK17默认的垃圾回收期是G1

-XX:+UseZGC

八、JVM常量API

在这里插入图片描述
比如String的源码,获取字符串常量的描述describeConstable,设置字符串常量的描述resolveConstantDesc

    /*** Returns an {@link Optional} containing the nominal descriptor for this* instance, which is the instance itself.** @return an {@link Optional} describing the {@linkplain String} instance* @since 12*/@Overridepublic Optional<String> describeConstable() {return Optional.of(this);}/*** Resolves this instance as a {@link ConstantDesc}, the result of which is* the instance itself.** @param lookup ignored* @return the {@linkplain String} instance* @since 12*/@Overridepublic String resolveConstantDesc(MethodHandles.Lookup lookup) {return this;}

九、重写Socket底层API

在这里插入图片描述
源码如下

public abstract class SocketImpl implements SocketOptions {private static final boolean USE_PLAINSOCKETIMPL = usePlainSocketImpl();private static boolean usePlainSocketImpl() {PrivilegedAction<String> pa = () -> NetProperties.get("jdk.net.usePlainSocketImpl");@SuppressWarnings("removal")String s = AccessController.doPrivileged(pa);return (s != null) && !s.equalsIgnoreCase("false");}/*** Creates an instance of platform's SocketImpl*/@SuppressWarnings("unchecked")static <S extends SocketImpl & PlatformSocketImpl> S createPlatformSocketImpl(boolean server) {if (USE_PLAINSOCKETIMPL) {return (S) new PlainSocketImpl(server);} else {return (S) new NioSocketImpl(server);}}
}

十、JDK飞行记录事件流

在这里插入图片描述

比如Spring Boot中Spring Boot Actuator模块可以启动记录JFR记录,可以通过在应用程序的配置文件中设置一下属性来启用JFR记录
在这里插入图片描述

十一、EdDSA签名算法

了解即可
在这里插入图片描述

十二、隐藏类

在这里插入图片描述

在这里插入图片描述

十三、对Value-Based类型的警告

在这里插入图片描述

十四、统一的PRNG接口(Enhanced Pseudo-Random Number Generators)

在这里插入图片描述

十五、特定于上下文的反序列化过滤器

在这里插入图片描述

十五、恢复始终严格的浮点语义

在这里插入图片描述

http://www.dtcms.com/a/305254.html

相关文章:

  • Java注解全面解析与应用实战
  • Redis 跨主机连接超时分析:从网络波动到架构优化
  • 关于算法的一些思考
  • 基于springboot的零食商城的设计与实现/零食销售系统的设计与实现
  • 基于Matlab图像处理的静态雨滴去除与质量评估系统
  • JAVA第五学:方法的使用 调试讲解
  • RAG实战指南 Day 26:RAG系统评估指标与方法
  • 2025年06月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • R语言中 read.table 和 read.delim 之间的区别
  • vue中使用wavesurfer.js绘制波形图和频谱图
  • 数学建模算法-day[14]
  • Java中写文件的显示大小实时性
  • 深入理解 boost::lock_guard<boost::mutex>
  • mybatis-plus由mysql改成达梦数据库
  • 【Linux】重生之从零开始学习运维之Mysql事务
  • Python day28
  • 破解企业无公网 IP 难题:可行路径与实现方法?
  • Three.js 渲染优化处理
  • 【C++算法】74.优先级队列_最后一块石头的重量
  • 查找特定的值
  • zama test
  • BGP团体属性
  • Linux部署各类软件
  • 《剑指offer》-算法篇-位运算
  • 【深度学习新浪潮】什么是世界模型?
  • 洛谷 P9779 [HUSTFC 2023] 不定项选择题
  • 记一次导出pdf表单引发的问题
  • Linux救援模式之简介篇
  • 文件相关问题(AI回答)
  • 【从0开始学习Java | 第5篇】封装