news 2026/9/5 7:15:59

从 JDK 8 到 JDK 17:那些改变 Java 开发方式的新特性

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从 JDK 8 到 JDK 17:那些改变 Java 开发方式的新特性

前言

2014 年 JDK 8 的发布无疑是 Java 历史的里程碑,Lambda 表达式和 Stream API 让 Java 正式拥抱函数式编程。然而在此之后,Java 的发布节奏发生了根本性变化——从 2018 年起,Oracle 采用“每 6 个月一个版本”的快节奏发布策略。JDK 17 于 2021 年 9 月发布,是继 JDK 8 和 JDK 11 之后的第三个 LTS(长期支持)版本,提供长达 8 年的官方支持。

从 JDK 8 到 JDK 17,Java 平台由约194 个 JEP(JDK Enhancement Proposals)塑造而成(根据官方 JEP 索引统计,部分草案被合并或撤回,实际数量略有浮动)。本文将从语言特性、API 更新和性能优化三个维度,梳理这其中最值得关注的新特性,包含每个特性的首次引入版本正式定稿版本对应 JEP 编号,以及官方文档和代码示例。


一、语言特性篇

1. 局部变量类型推断——var(JEP 286)

var关键字允许编译器根据初始化表达式推断局部变量的类型,减少了冗余的类型声明。

项目内容
首次引入(预览)JDK 10 Early Access(需--enable-preview
正式定稿JDK 10 正式版
JEPJEP 286: Local-Variable Type Inference
官方文档Local Variable Type Inference
// JDK 8 写法List<String>list=newArrayList<String>();Map<String,List<Integer>>map=newHashMap<String,List<Integer>>();// JDK 10+ 写法varlist=newArrayList<String>();varmap=newHashMap<String,List<Integer>>();vargreeting="Hello World!";// 推断为 String

注意var只能用于局部变量,不能用于字段、方法参数或返回类型。


2. Switch 表达式(JEP 325 → JEP 354 → JEP 361)

传统的switch是语句(statement),而 Switch 表达式(expression)可以直接返回一个值,配合箭头语法->yield,代码更加简洁安全。

项目内容
首次引入(预览)JDK 12(JEP 325)
第二次预览JDK 13(JEP 354)
正式定稿JDK 14(JEP 361)
官方文档Java Language Changes Summary
// JDK 8 写法(语句)intnumLetters;switch(day){caseMONDAY:caseFRIDAY:caseSUNDAY:numLetters=6;break;caseTUESDAY:numLetters=7;break;default:numLetters=0;}// JDK 14+ 写法(表达式)intnumLetters=switch(day){caseMONDAY,FRIDAY,SUNDAY->6;caseTUESDAY->7;default->{Strings=day.toString();yields.length();// yield 返回值}};

3. 文本块(Text Blocks)(JEP 355 → JEP 368 → JEP 378)

文本块解决了 Java 中多行字符串拼接的痛点,无需大量转义字符即可书写格式化的多行文本。

项目内容
首次引入(预览)JDK 13(JEP 355)
第二次预览JDK 14(JEP 368)
正式定稿JDK 15(JEP 378)
官方文档Java Language Changes Summary
// JDK 8 写法Stringhtml="<html>\n"+" <body>\n"+" <p>Hello, world</p>\n"+" </body>\n"+"</html>";// JDK 15+ 写法(文本块)Stringhtml=""" <html> <body> <p>Hello, world</p> </body> </html> """;

4.instanceof模式匹配(JEP 305 → JEP 375 → JEP 394)

将“类型检查”和“类型转换”合二为一,这是你在问题中提到的语法。

项目内容
首次引入(预览)JDK 14(JEP 305)
第二次预览JDK 15(JEP 375)
正式定稿JDK 16(JEP 394)
官方文档Pattern Matching for instanceof
// JDK 8 写法if(objinstanceofString){Strings=(String)obj;System.out.println(s.toUpperCase());}// JDK 16+ 写法(模式匹配)if(objinstanceofStrings){System.out.println(s.toUpperCase());}// 配合 && 使用if(objinstanceofStrings&&s.length()>5){System.out.println("长度大于5: "+s.toUpperCase());}

5. Record 类(JEP 359 → JEP 384 → JEP 395)

Record 是一种透明的数据载体,编译器自动生成构造器、equals()hashCode()toString(),彻底告别 POJO 的模板代码。

项目内容
首次引入(预览)JDK 14(JEP 359)
第二次预览JDK 15(JEP 384)
正式定稿JDK 16(JEP 395)
官方文档Record Classes
// JDK 8 写法(需要 50+ 行代码)publicclassPerson{privatefinalStringname;privatefinalintage;publicPerson(Stringname,intage){this.name=name;this.age=age;}publicStringgetName(){returnname;}publicintgetAge(){returnage;}// equals()、hashCode()、toString() 等...}// JDK 16+ 写法(1 行搞定)publicrecordPerson(Stringname,intage){}// 使用varperson=newPerson("Alice",30);System.out.println(person.name());// 访问器方法自动生成System.out.println(person.age());

6. 密封类(Sealed Classes)(JEP 360 → JEP 397 → JEP 409)

密封类允许开发者限制哪些类可以继承或实现某个类/接口,提供更精细的继承控制。

项目内容
首次引入(预览)JDK 15(JEP 360)
第二次预览JDK 16(JEP 397)
正式定稿JDK 17(JEP 409)
官方文档Sealed Classes
// 定义一个密封类 Shape,只允许 Circle 和 Rectangle 继承publicabstractsealedclassShapepermitsCircle,Rectangle{// ...}publicfinalclassCircleextendsShape{privatefinaldoubleradius;publicCircle(doubleradius){this.radius=radius;}publicdoubleradius(){returnradius;}}publicfinalclassRectangleextendsShape{privatefinaldoublewidth,height;publicRectangle(doublewidth,doubleheight){this.width=width;this.height=height;}publicdoublewidth(){returnwidth;}publicdoubleheight(){returnheight;}}// Triangle 尝试继承 Shape → 编译错误publicfinalclassTriangleextendsShape{}// Compile error

注意:密封类与 Switch 表达式配合使用时,若 Switch 模式匹配(见第 7 节)处于预览状态,代码需要--enable-preview参数才能编译和运行。以下示例综合了两项特性:

// 需要 JDK 17 + --enable-preview(因为 Switch 模式匹配为预览特性)doublearea=switch(shape){caseCirclec->Math.PI*Math.pow(c.radius(),2);caseRectangler->r.width()*r.height();// 无需 default,编译器知道所有情况已覆盖};

7. Switch 的模式匹配(JEP 406 → JEP 420 → JEP 427 → JEP 433)

将模式匹配从instanceof扩展到switch,支持类型模式、守卫模式等,是 Java 模式匹配能力的重要延伸。

重要说明:本节讨论的 Switch 模式匹配特性虽在 JDK 17 中首次预览(JEP 406),但正式定稿在 JDK 21(JEP 441)。本博客以 JDK 17 LTS 为核心,但为了展示语法演进全貌,特此收录。以下代码示例基于 JDK 17 预览版编写,必须配合--enable-preview参数使用。

项目内容
首次引入(预览)JDK 17(JEP 406)
第二次预览JDK 18(JEP 420)
第三次预览JDK 19(JEP 427)
第四次预览JDK 20(JEP 433)
正式定稿JDK 21(JEP 441)—注:超出 JDK 17 范围
官方文档Pattern Matching for Switch
// JDK 17(预览)支持类型模式和守卫模式Stringformatted=switch(obj){caseIntegeri&&i>10->String.format("大整数 %d",i);caseIntegeri->String.format("小整数 %d",i);caseLongl->String.format("长整数 %d",l);casenull->"null";default->obj.toString();};

8. 接口私有方法(JEP 213——Milling Project Coin)

JDK 9 允许在接口中定义private方法,用于在default方法之间共享公共代码。该特性直接定稿,无预览阶段。

项目内容
首次引入(正式定稿)JDK 9
JEPJEP 213: Milling Project Coin
官方文档Java Language Changes for Java SE 9
publicinterfaceCalculator{defaultintadd(inta,intb){returnprocess(a,b,"add");}defaultintsubtract(inta,intb){returnprocess(a,b,"subtract");}// 私有方法,供 default 方法复用privateintprocess(inta,intb,Stringoperation){System.out.println("执行: "+operation);returnoperation.equals("add")?a+b:a-b;}}

二、API 与库更新篇

9. 工厂方法创建不可变集合(JEP 269)

JDK 9 为ListSetMap提供了便捷的静态工厂方法,快速创建不可变集合。该特性直接定稿,无预览阶段。

项目内容
首次引入(正式定稿)JDK 9
JEPJEP 269: Convenience Factory Methods for Collections
// JDK 8 写法List<String>list=newArrayList<>();list.add("a");list.add("b");list.add("c");list=Collections.unmodifiableList(list);// JDK 9+ 写法List<String>list=List.of("a","b","c");Set<String>set=Set.of("x","y","z");Map<String,Integer>map=Map.of("key1",1,"key2",2);

10. 增强的伪随机数生成器(JEP 356 → JEP 371)

JDK 17 引入了新的伪随机数生成器 API(RandomGenerator接口),提供了更强大、更灵活的随机数生成能力。注意:该 API 在 JDK 17 中为预览特性

项目内容
首次引入(预览)JDK 17(JEP 356)
正式定稿JDK 18(JEP 371)
官方文档JDK 17 Release Notes
// 旧方式Randomrandom=newRandom();intvalue=random.nextInt(100);// JDK 17+(预览)新方式,JDK 18 正式可用RandomGeneratorgenerator=RandomGenerator.of("L128X1024MixRandom");intvalue=generator.nextInt(100);

11. 有用的 NullPointerException(JEP 358)

JDK 14 开始,NullPointerException会精确指出哪个变量null,极大提升了调试效率。该特性直接定稿,无预览阶段。

项目内容
首次引入(正式定稿)JDK 14
JEPJEP 358: Helpful NullPointerExceptions
// 代码a.b.c.i=99;// JDK 8 的异常信息Exceptionin thread"main"java.lang.NullPointerExceptionatTest.main(Test.java:3)// JDK 14+ 的异常信息(精确指出 null 的位置)Exceptionin thread"main"java.lang.NullPointerException:Cannotread field"c"because"a.b"isnullatTest.main(Test.java:3)

12. JShell——REPL 工具(JEP 222)

JDK 9 引入了 JShell,一个交互式的 Java REPL(Read-Eval-Print Loop)工具,允许开发者在不编写完整类的情况下快速测试代码片段。该特性直接定稿,无预览阶段。

项目内容
首次引入(正式定稿)JDK 9
JEPJEP 222: JShell: The Java Shell
$ jshell|欢迎使用 JShell -- 版本17|要大致了解该版本,请键入:/help intro jshell>var list=List.of(1,2,3)list==>[1,2,3]jshell>list.stream().map(n ->n *2).toList()$2==>[2,4,6]

三、性能与运行时篇

13. Java 平台模块系统(Project Jigsaw)(JEP 261)

JDK 9 最重大的变化——模块化系统(JPMS),将 JDK 本身模块化,并允许开发者创建自己的模块。该特性直接定稿,无预览阶段。

项目内容
首次引入(正式定稿)JDK 9
JEPJEP 261: Module System
官方文档Project Jigsaw
// module-info.javamodulecom.example.myapp{requiresjava.sql;requireshu.advancedweb.somedependency;exportscom.example.myapp.api;}

14. ZGC——可扩展的低延迟垃圾回收器(JEP 333 → JEP 377)

ZGC 是一种可扩展的低延迟垃圾回收器,暂停时间不超过 10 毫秒,且不随堆大小增加而增加。

项目内容
首次引入(实验性)JDK 11(JEP 333)
正式产品化JDK 15(JEP 377)
官方文档ZGC: The Z Garbage Collector
# 启用 ZGC(需显式指定)java-XX:+UseZGC-jarmyapp.jar

关于“默认”的澄清:JDK 17默认增强了对 ZGC 和 Shenandoah 的支持(如性能优化和平台兼容性提升),但垃圾回收器本身并未默认启用。开发者仍需通过-XX:+UseZGC显式开启,方可实现毫秒级停顿。


15. 强封装 JDK 内部 API(JEP 403)

从 JDK 17 开始,JDK 内部 API(如sun.misc.Unsafe)被默认强封装,应用程序无法再通过反射随意访问。

项目内容
首次引入(正式定稿)JDK 17
JEPJEP 403: Strongly Encapsulate JDK Internals
官方文档Oracle JDK Migration Guide
# 注意:--illegal-access 参数在 JDK 16 中已被标记为废弃(deprecated),# JDK 17 中默认行为已从 permit 改为 deny,并在 JDK 18 中被彻底移除。# 更推荐通过 --add-opens 等模块参数精确控制访问权限。# 不推荐(JDK 16+ 废弃警告,JDK 17 默认 deny,JDK 18+ 报错)java--illegal-access=permit-jarmyapp.jar# 推荐方式(精确开放特定包)java--add-opens java.base/java.lang=ALL-UNNAMED-jarmyapp.jar

四、各版本 JEP 数量一览

版本发布时间是否 LTS主要 JEP 数量
JDK 82014.03✅ LTS56
JDK 92017.09
JDK 102018.03
JDK 112018.09✅ LTS17
JDK 122019.03
JDK 132019.09
JDK 142020.03
JDK 152020.09
JDK 162021.03
JDK 172021.09✅ LTS14

从 JDK 8 到 JDK 17,共涉及约 194 个 JEP(具体数字因统计口径略有浮动)。


五、迁移建议

从 JDK 8 升级到 JDK 17 并非没有挑战,但也带来了显著收益:

维度提升
启动速度提升 30%+
内存占用降低 20%+
代码量借助 Record、var 等特性可减少 40%+
GC 停顿ZGC 实现毫秒级停顿

需要注意的兼容性问题

  • JDK 内部 API(如sun.misc.Unsafe)被强封装,依赖这些 API 的库可能需要升级,废弃的--illegal-access参数需替换为--add-opens
  • 模块化系统可能影响类路径上的某些遗留代码。
  • Spring Boot 3.x 已强制要求 JDK 17+。

参考资源

  • OpenJDK JEP 索引:https://openjdk.org/jeps/
  • Oracle Java SE 17 文档:https://docs.oracle.com/en/java/javase/17/
  • Java Language Changes Summary:https://docs.oracle.com/en/java/javase/17/language/java-language-changes-summary.html
  • Java SE 17 规范(JSR 392):https://cr.openjdk.java.net/~iris/se/17/latestSpec/
  • JDK 17 Release Notes:https://docs.oracle.com/en/java/javase/17/docs/api/

结语

JDK 17 不仅是 Java 8 之后最重要的 LTS 版本,更代表了 Java 语言演进的“新常态”——从过去的“大版本大更新”转向“小步快跑、持续交付”。语法层面,var、Record、Sealed Class、模式匹配等特性让 Java 代码更加简洁、安全;运行时层面,ZGC、模块化、强封装内部 API 等改进让 Java 在现代云原生环境中更具竞争力。

如果你还在使用 JDK 8,是时候认真考虑升级到 JDK 17 了——这不仅是一次版本升级,更是一次开发范式的跃迁

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 7:15:35

视觉驱动自动化:从OCR与CV原理到工程化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 7:15:22

第21篇|文件下载库适配 HarmonyOS:断点续传、沙盒目录和进度回调

第21篇&#xff5c;文件下载库适配 HarmonyOS&#xff1a;断点续传、沙盒目录和进度回调 图 1&#xff1a;文件下载库适配封面图&#xff0c;用来概括本文主题、适配对象和工程边界。 实际项目里&#xff0c;文件下载库适配经常不是“引入依赖就能用”的问题。真正麻烦的是输入…

作者头像 李华
网站建设 2026/9/5 7:12:32

PTP协议硬件时间戳详解:纳秒级精度的实现原理与工程实践

PTP协议精讲&#xff08;3.8&#xff09;&#xff1a;硬件时间戳详解——纳秒级精度的魔法搞网络时间同步这行的人&#xff0c;一定听过一句口头禅&#xff1a;"软件时间戳看运气&#xff0c;硬件时间戳看设计&#xff0c;纳秒级精度全靠硬件时间戳在撑场子。"这句话…

作者头像 李华
网站建设 2026/9/5 7:11:42

i.MX6ULL平台设备与驱动匹配机制详解

搞i.MX6ULL驱动开发的&#xff0c;十有八九都会在Platform机制上卡过一阵子。明明驱动代码写了&#xff0c;设备树也配了&#xff0c;结果probe就是不进&#xff0c;或者模块加载了一堆报错&#xff0c;不知道从哪查起。这篇文章我把自己在i.MX6ULL上折腾Platform设备与驱动匹配…

作者头像 李华
网站建设 2026/9/5 7:11:01

视觉AI项目部署指南:从环境配置到效果验证的完整实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 7:09:58

链表与递归实战:反转链表与两两交换节点(LeetCode 206 24)

一、递归基础递归就是函数调用自身。如果一个递归调用是最后一条执行语句&#xff0c;称为尾递归。递归模型由两部分组成&#xff1a;递归出口&#xff08;结束条件&#xff09;和递归体&#xff08;递推关系&#xff09;。比如求 n!&#xff1a;递归出口&#xff1a;fun(1) 1…

作者头像 李华