JDK17新特性梳理

news/2025/9/30 18:46:31/文章来源:https://www.cnblogs.com/randolf/p/19121651

JDK17新特性梳理

一、为什么JDK17

  1. 生态强制升级

    业界长期 “你发任你发,我用 Java8”,但 Spring Framework 6.0+ 明确要求 Java 17+Spring Boot 3.2+ 不仅要求 Java 17+,还需依赖 Spring Framework 6.1.1+,且仅支持特定构建工具版本:

    Build Tool 最低版本要求
    Maven 3.6.3
    Gradle 7.5+(7.x 系列)、8.x 系列
  2. 版本定位关键

    • JDK8 后首个生态成熟的 LTS 长期支持版本,比 JDK11 生态更完善;
    • 建议跳过 JDK11 直接升级:JDK21 仅 “虚拟线程” 特性亮眼,其他特性对 JDK17 无显著优势。

二、语法层新特性

1.文本块

  • 功能:解决多行字符串换行转义问题,用连续三个双引号包裹,支持 String.format

  • 新增转义符:\(置于行尾,连接上下两行)、\s(表示单个空字符);

  • 示例:

    String query = """
    SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` \s
    WHERE `CITY` = '%s' \
    ORDER BY `EMP_ID`, `LAST_NAME`;
    """;
    System.out.println(String.format(query, "合肥")); // 输出无转义符的正确SQL
    

2.Switch 表达式增强

  • 核心升级:支持 “语句” 与 “表达式” 双模式,新增多值匹配、yield 关键字(替代 break 返回值);

  • 示例 1(多值匹配):

    switch (name) {case "李白", "杜甫", "白居易" -> System.out.println("唐代诗人");case "苏轼", "辛弃疾" -> System.out.println("宋代诗人");default -> System.out.println("其他朝代诗人");
    }
    
  • 示例 2(作为表达式):

    int tmp = switch (name) {case "李白", "杜甫", "白居易" -> 1;case "苏轼", "辛弃疾" -> 2;default -> {System.out.println("其他朝代诗人");yield 3; // 返回默认值}
    };
    

3.instanceof 的模式匹配

  • 功能:判断变量类型后,无需手动强转,直接在分支中使用匹配类型的变量;

  • 示例:

    if (o instanceof Integer i && i > 0) {System.out.println(i.intValue()); // 直接用i,无需强转
    } else if (o instanceof String s && s.startsWith("t")) {System.out.println(s.charAt(0)); // 直接用s
    }
    

4.var 局部变量推导

  • 功能:对类型可直接推导的局部变量,用 var 声明,简化代码;

  • 示例:

    var nums = new int[] {1, 2, 3, 4, 5}; // 推导为int[]
    var sum = Arrays.stream(nums).sum(); // 推导为int
    
  • 注意:需权衡 “简化代码” 与 “Java 强类型安全性”,仁者见仁。

三、模块化及类封装

1.记录类(record)

  • 定位:不可变数据结构,替代 BO/VO/DTO 等仅用于值传递的复杂对象;
  • 特性:
    • JDK14 引入,JDK16 正式转正
    • 声明时直接定义属性(如 public record Point(int x, int y) {}),初始化后属性不可修改(反射也不行);
    • 自动生成 toString()hashCode()equals() 且为 final,不可定制;
    • 属性获取方法为 “属性名 ()”(如 p.x()),而非传统 getX()

2.隐藏类(Hidden Classes)

  • 引入版本:JDK15
  • 核心逻辑:不依赖类加载器,通过读取目标类字节码创建 “对其他类隐藏的 Class 对象”,再通过反射调用;
  • 价值:提升 Java 动态语言能力,替代 Spring 等框架中繁琐低效的 ASM 字节码操作,成为动态类生成的新标准。
// 步骤1:同样用ASM生成代理类的字节码(和JDK8一样,字节码生成逻辑不变)
byte[] proxyBytes = ...; // 动态生成的代理类字节码// 步骤2:直接通过MethodHandles生成隐藏类(无需关心类加载器)
MethodHandles.Lookup lookup = MethodHandles.lookup();
// 关键API:defineHiddenClass(字节码数组 + 是否初始化 + 嵌套类选项)
Class<?> hiddenProxyClass = lookup.defineHiddenClass(proxyBytes, true, MethodHandles.Lookup.ClassOption.NESTMATE).lookupClass();// 步骤3:通过MethodHandle调用方法(无法直接引用类型,只能间接调用)
// 3.1 获取构造方法,创建实例
Constructor<?> constructor = hiddenProxyClass.getConstructor();
Object proxyInstance = constructor.newInstance();// 3.2 获取sayHello方法,调用
Method sayHelloMethod = hiddenProxyClass.getMethod("sayHello", String.class);
String result = (String) sayHelloMethod.invoke(proxyInstance, "张三");
System.out.println(result);// 优势:
// 1. 代理类对其他类不可见(不能写 UserServiceProxy proxy = ...);
// 2. hiddenProxyClass无人引用后,会被GC回收,无内存泄漏;
// 3. 无需手动实现类加载器,API更简洁,不易出错。

3.密封类(Sealed Classes)

  • 转正版本:JDK17
  • 功能:限制父类的子类范围,防止随意继承打破内置行为(如 JDK8 类加载双亲委派可被随意修改的安全问题);
  • 使用规则:
    • 父类用 sealed 修饰,需通过 permits 指定允许的子类(如 public sealed abstract class Shape permits Circle, Rectangle, Square {});
    • 子类需声明密封属性:final(不可继承)、non-sealed(可随意继承)、sealed(继续用 permits 指定子类)(public non-sealed class Square extends Shape);
  • 限制:父类与子类必须在同一显式命名的 module 下,且子类需直接继承父类。

4.模块化系统(Module System)

  • 定义:JDK9 引入,是 package 上层的抽象,聚合相关包与资源,通过 module-info.java 描述,JDK17 中以 .jmod 文件替代传统 .jar 文件;

  • 核心操作:

    1. 声明模块:在模块根目录创建 module-info.java,用 module 关键字声明(如 module roy.demomodule {}),模块名需全局唯一(惯例小写,用.连接);
    2. 声明依赖(require)
      • 依赖外部模块:如依赖 JUnit 需 requires junit;(非模块化 Jar 包默认模块名为 “去掉版本的 Jar 名”);
      • 依赖 JDK 内置模块:如用 JDBC 需 requires java.sql;
      • 编译时依赖:requires static(仅编译需该模块,运行时可选,类似 Maven 的 compile scope);
    3. 暴露 API(exports/opens)
      • exports 包名:对外开放指定包,编译和运行时可访问,但不支持反射;
      • opens 包名:对外开放指定包,支持反射访问(解决跨模块反射调用报错问题);
    4. 服务机制(uses/provides)
      • 服务提供方(如 demoModule2):用 provides 接口名 with 实现类1, 实现类2; 暴露服务(需先 exports 接口所在包);
      • 服务调用方(如 demoModule):用 uses 接口名; 声明使用服务,通过 ServiceLoader.load(接口名) 调用;
    5. 构建模块化 Jar 包
      • 执行命令:java --module-path 模块路径 -m 模块名/主类全路径(如 java --module-path demoModule.jar:demoModule2.jar -m roy.demomodule/com.roy.spi.ServiceDemo);
      • 查看模块:java --module-path 模块路径 --list-modules
  • 类加载机制调整

    JDK8 类加载体系 JDK9+(含 JDK17)类加载体系 核心调整点
    BootstrapClassLoader(根加载器) BootstrapClassLoader 1. 替换扩展加载器:用 PlatformClassLoader 替代 ExtClassLoader,因模块化天生支持扩展,无需 ExtClassLoader;2. 调整父类:PlatformClassLoader 与 AppClassLoader 继承自 BuildinClassLoader(实现模块化类加载逻辑);3. 双亲委派优化:Platform/AppClassLoader 加载类前,先判断类所属系统模块,优先委派给对应模块的加载器
    ExtClassLoader(扩展加载器) PlatformClassLoader(平台类加载器)
    AppClassLoader(应用类加载器) AppClassLoader
    自定义类加载器 自定义类加载器

四、GC 调整

  1. ZGC 转正
    • 引入:JDK11 预览,JDK15 正式投入使用,JDK17 中相关参数已稳定;
    • 启用:-XX:+UseZGC
    • 补充:支持 RedHat 的 Shenandoah 垃圾回收器,启用参数 XX:+UseShenandoahGC(Oracle 以可选方案集成)。
  2. 废除 CMS
    • 时间:JDK14 彻底删除
    • 原因:G1 已完善,ZGC/Shenandoah 等现代 GC 更高效,CMS 实现复杂;
    • 同步删除:Serial 垃圾回收器、SerialOld(原作为 CMS 补充方案)。

五、GraalVM 虚拟机

  1. 背景
    • 定位:替代 HotSpot 的潜力虚拟机,用 Java 编写(对比 C/C++ 编写的 C1/C2 编译器,更易维护);
    • 核心能力:支持 JIT(即时编译)AOT(提前编译),解决 Java 微服务场景下 “启动慢、预热久” 的痛点,适配云原生;
    • 生态支持:Spring Boot、Micronaut 等微服务框架,Oracle Cloud、AWS 等云平台均支持。
  2. 使用步骤
    1. 下载:官网(https://www.graalvm.org)下载对应版本(当前支持 Java17/21);
    2. 配置:解压后配置 JAVA_HOME,验证 java -version(显示 “Oracle GraalVM”);
    3. 基础使用:与普通 JDK 一致(javac 编译java 执行);
    4. AOT 编译(本地镜像):
      • 命令:native-image 类名(需先安装 zlib-devel 依赖,解决 “找不到 -lz” 错误);
      • 优势:本地镜像无需 JVM 即可运行,启动速度极快(示例 Hello 程序执行时间 real 0m0.006s,远快于普通 JDK 的 0.059s)。

关键问题及答案

问题 1:为什么说 JDK17 是 JDK8 时代程序员的 “必选项”,而非 “可选项”?其生态支持的核心依据是什么?

答案:JDK17 成为 “必选项” 的核心原因的两点:

  1. 生态强制绑定:作为 Java 应用基石的 Spring Framework 6.0+ 明确要求 “Java 17+”,Spring Boot 3.2+ 不仅要求 “Java 17+”,还需依赖 Spring Framework 6.1.1+,且仅支持 Maven 3.6.3+、Gradle 7.5 + 等工具,若不升级 JDK17,无法使用主流框架的新版本特性;
  2. 版本性价比最优:JDK17 是 JDK8 后首个生态成熟的 LTS 版本,相比 JDK11 生态更完善;而 JDK21 仅 “虚拟线程” 特性亮眼,其他特性对开发效率提升有限,跳过 JDK11 直接升级 JDK17 更实惠,避免多次升级成本。

问题 2:JDK17 中 “record 记录类” 与传统 POJO 相比,核心差异是什么?在实际开发中适合解决什么问题?

答案:核心差异及适用场景如下:

对比维度 record 记录类 传统 POJO
不可变性 属性默认private final,初始化后不可修改(反射也不行) 需手动添加private final,否则属性可修改
方法生成 自动生成toString()hashCode()equals(),且方法为final(不可重写) 需手动编写或依赖 Lombok 生成,方法可重写
属性访问 用 “属性名 ()” 获取(如p.x() getX()获取(需遵循 JavaBean 规范)
适用场景 仅用于值传递的场景(如 BO/VO/DTO),无需定制业务逻辑 需包含业务逻辑(如属性修改、复杂方法)的对象
实际开发中,record 记录类可大幅简化 “仅承载数据、无业务逻辑” 的类定义,减少模板代码(如无需写 getter/toString 等),提升开发效率。

问题 3:JDK17 模块化系统(Module System)相比 JDK8 的 “包机制”,最大的改进是什么?对大型项目开发有何实际价值?

答案:最大改进是 从 “包级别的代码组织” 升级为 “模块级别的资源隔离与依赖管理”,JDK8 的包机制仅能通过访问修饰符(public/private)控制类访问范围,无法限制跨包 / 跨 Jar 的依赖;而模块化系统通过module-info.java实现:

  1. 精确依赖管理:用require明确声明依赖的模块,避免 “隐式依赖” 导致的版本冲突(如依赖 JDK 内置功能需显式requires java.sql);

  2. 资源隔离:用exports/opens仅暴露必要的 API,隐藏内部实现(如仅对外开放com.roy.service包,内部com.roy.util包不暴露),降低耦合;

  3. 定制轻量 JRE:基于.jmod文件,通过jlink -p $JAVA_HOME/jmods --add-modules 所需模块 --output 自定义JRE生成仅含项目所需模块的 JRE(如仅用java.base模块),减少部署体积,适配云原生轻量化需求;

    对大型项目而言,这些改进可降低跨团队协作的依赖冲突风险,简化多模块项目的管理,同时减少线上部署资源占用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/923154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构学习随笔 第一章

数据结构学习随笔 第一章该内容全部引用于 《数据结构 C 语言 第二版》 严蔚敏 李冬梅 吴伟民 著绪论 只有清楚数据的内在联系,合理地组织数据,才能对它们进行有效的处理,设计出高效的算法。 1.1 数据结构研究的内容…

函数-参数+作用域

参数:定义函数时(参数常见的使用):1. def i(num)  2. def i(num1,num2 = 自己定义)  3.def i(*arg,*kwarg)调用函数时 (参数的传入):位置参数>关键字参数不定长参数:*args:调用函数时使用位置传…

怎么给网站制作二维码毕业设计做网站好的想法

互联网IT外包15年,讲述外包那些事;让您外包项目少花钱,办好事&#xff01;IT外包最大隐形成本-沟通成本&#xff1a;客户叙述大概需求,IT公司说一做一,最后开发项目细节大堆BUG,毫无用户体验感,最后项目一拖再拖,无限延期&#xff01;究其原因,客户非IT行内人,对系统功能及流程…

用 Nim 实现英文数字验证码识别

一、背景介绍 验证码识别是图像识别领域的常见任务。本文将使用 Nim 语言 编写一个简洁的工具,调用 Tesseract OCR 来实现英文数字验证码的识别。Nim 拥有接近 C 的性能,同时提供了简洁的语法和强大的标准库,非常适…

vip视频网站怎么做装饰公司网站

2020年7月21日晚&#xff0c;GOG官方宣布提供与Epic商城的集成服务&#xff0c;这也是GOG GALAXY 2.0推出以来又一次与超大型游戏平台达成的合作。现在玩家可以通过GOG GALAXY 2.0管理、安装和启动来自Epic商城的游戏。需要注意的是&#xff0c;因为这次行为是完全官方的&#…

游戏开发与网站开发哪个难wordpress注册邮件

6月9日&#xff0c;在2020阿里云线上峰会上&#xff0c;阿里巴巴集团副总裁、数据技术及产品部负责人朋新宇推出Quick Audience、Quick A两款全新产品&#xff0c;并升级Dataphin和Quick BI两款现有产品。同时&#xff0c;阿里云零售、金融、政务及互联网企业等四大行业数据中台…

思路探索:当大型语言模型遇见数据分析的现实挑战 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

抓紧上车,别再错过啦, Github 开源后台管理平台,Naive UI !!!

嗨,我是小华同学,专注解锁高效工作与前沿AI工具!每日精选开源技术、实战技巧,助你省时50%、领先他人一步。👉免费订阅,与10万+技术人共享升级秘籍!naive-ui-pro 是一套完全免费的企业级中后台系统模板,基于 V…

顺德高端网站招商码头无忧查询系统

foreach函数是PHP中用于遍历数组或对象的函数&#xff08;且仅用于数组的遍历&#xff09;。它允许循环遍历数组中的每个元素&#xff0c;并对每个元素执行相同的操作。foreach语句的基本语法如下&#xff1a; foreach ($array as $value) {//执行的操作 }在这个语法中&#x…

惠州附近做商城网站建设哪家好做外贸的怎么建立自己的网站

sprintf()函数 这个函数在 stdio.h中&#xff1b;可以将格式化的数据写入到一个字符串缓冲区中。 int sprintf(char *str, const char *format, ...);str&#xff1a;指向字符数组的指针&#xff0c;即用于存储格式化后字符串的缓冲区。format&#xff1a;格式化字符串&#…

实用指南:电子电气架构 --- 智能座舱域环境感知和人机交互系统

实用指南:电子电气架构 --- 智能座舱域环境感知和人机交互系统pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…

【机器学习】朴素贝叶斯法 - 实践

【机器学习】朴素贝叶斯法 - 实践2025-09-30 18:28 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impor…

网站开发 承接wordpress modernizr

作者&#xff1a;黄天元&#xff0c;复旦大学博士在读&#xff0c;热爱数据科学与开源工具&#xff08;R&#xff09;&#xff0c;致力于利用数据科学迅速积累行业经验优势和科学知识发现&#xff0c;涉猎内容包括但不限于信息计量、机器学习、数据可视化、应用统计建模、知识图…

汾阳网站建设用ps网站首页怎么做

文章目录 Dubbo的发展背景单一应用架构垂直应用架构分布式服务架构流动计算架构 RPCRPC的简单原理 DubboDubbo是什么Dubbo作者Dubbo的发展历程Dubbo架构 Dubbo发音&#xff1a; |ˈdʌbəʊ| Dubbo官方网站&#xff1a;http://dubbo.apache.org/ Dubbo是阿里巴巴开发的&#…

【Rust GUI开发入门】编写一个本地音乐播放器(8. 从文件中提取歌曲元信息) - Jordan

本系列教程对应的代码已开源在 Github zeedle 目的是从.mp3/.flac/.wav/...文件中提取歌曲名称/艺术家/音频时长信息/歌词信息/专辑封面 添加依赖 使用lofty这个全能解析库,将其添加到Cargo.toml中: lofty = "0…

Tita项目与绩效一体化管理:重构组织效能的数字化中枢

在数字化转型的深水区,企业正面临一个核心命题:如何让项目管理从成本中心转变为价值创造引擎?Tita项目经营管理一体化平台以”项目-绩效-人才”三位一体为设计原点,通过打破传统管理系统的数据孤岛,构建起覆盖战略…

深入解析:【网络编程】套接字入门:网络字节序与套接字种类剖析

深入解析:【网络编程】套接字入门:网络字节序与套接字种类剖析pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "C…

网站开发google四川网站建设费用

Lucene查询语法&#xff0c;适用于 ELk Kibana 查询 Elasticsearch 构建在 Lucene 之上&#xff0c;过滤器语法和 Lucene 相同。本语法可用于 Kibana 界面的检索和 Grafana 看板对接 ES 的检索规则。 Kibana 上的检索语法Grafana 上的检索语法 全文搜索 在搜索栏输入login&…

地产行业,居然还有这样的开发商 - 智慧园区

今年《政府工作报告》明确提出,抓紧构建房地产发展新模式,促进房地产高质量发展。 从过去的“探索推动”到今年的“加快构建”,表明房地产新模式已进入实质落地阶段。 房企转型,要过去的以开发为主,转向开发与经营…

公司网站建设教程哪个网站有摄影作品

深度学习中常用的损失函数多种多样&#xff0c;具体选择取决于任务类型和问题的性质。以下是一些常见的深度学习任务和相应的常用损失函数&#xff1a; 分类任务&#xff1a; 交叉熵损失函数&#xff08;Cross-Entropy Loss&#xff09;&#xff1a;用于二分类和多类别分类任务…