ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

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

从 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 17Java 平台由约194 个 JEPJDK Enhancement Proposals塑造而成根据官方 JEP 索引统计部分草案被合并或撤回实际数量略有浮动。本文将从语言特性、API 更新和性能优化三个维度梳理这其中最值得关注的新特性包含每个特性的首次引入版本、正式定稿版本、对应 JEP 编号以及官方文档和代码示例。一、语言特性篇1. 局部变量类型推断——varJEP 286var关键字允许编译器根据初始化表达式推断局部变量的类型减少了冗余的类型声明。项目内容首次引入预览JDK 10 Early Access需--enable-preview正式定稿JDK 10 正式版JEPJEP 286: Local-Variable Type Inference官方文档Local Variable Type Inference// JDK 8 写法ListStringlistnewArrayListString();MapString,ListIntegermapnewHashMapString,ListInteger();// JDK 10 写法varlistnewArrayListString();varmapnewHashMapString,ListInteger();vargreetingHello World!;// 推断为 String注意var只能用于局部变量不能用于字段、方法参数或返回类型。2. Switch 表达式JEP 325 → JEP 354 → JEP 361传统的switch是语句statement而 Switch 表达式expression可以直接返回一个值配合箭头语法-和yield代码更加简洁安全。项目内容首次引入预览JDK 12JEP 325第二次预览JDK 13JEP 354正式定稿JDK 14JEP 361官方文档Java Language Changes Summary// JDK 8 写法语句intnumLetters;switch(day){caseMONDAY:caseFRIDAY:caseSUNDAY:numLetters6;break;caseTUESDAY:numLetters7;break;default:numLetters0;}// JDK 14 写法表达式intnumLettersswitch(day){caseMONDAY,FRIDAY,SUNDAY-6;caseTUESDAY-7;default-{Stringsday.toString();yields.length();// yield 返回值}};3. 文本块Text BlocksJEP 355 → JEP 368 → JEP 378文本块解决了 Java 中多行字符串拼接的痛点无需大量转义字符即可书写格式化的多行文本。项目内容首次引入预览JDK 13JEP 355第二次预览JDK 14JEP 368正式定稿JDK 15JEP 378官方文档Java Language Changes Summary// JDK 8 写法Stringhtmlhtml\n body\n pHello, world/p\n /body\n/html;// JDK 15 写法文本块Stringhtml html body pHello, world/p /body /html ;4.instanceof模式匹配JEP 305 → JEP 375 → JEP 394将“类型检查”和“类型转换”合二为一这是你在问题中提到的语法。项目内容首次引入预览JDK 14JEP 305第二次预览JDK 15JEP 375正式定稿JDK 16JEP 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(objinstanceofStringss.length()5){System.out.println(长度大于5: s.toUpperCase());}5. Record 类JEP 359 → JEP 384 → JEP 395Record 是一种透明的数据载体编译器自动生成构造器、equals()、hashCode()和toString()彻底告别 POJO 的模板代码。项目内容首次引入预览JDK 14JEP 359第二次预览JDK 15JEP 384正式定稿JDK 16JEP 395官方文档Record Classes// JDK 8 写法需要 50 行代码publicclassPerson{privatefinalStringname;privatefinalintage;publicPerson(Stringname,intage){this.namename;this.ageage;}publicStringgetName(){returnname;}publicintgetAge(){returnage;}// equals()、hashCode()、toString() 等...}// JDK 16 写法1 行搞定publicrecordPerson(Stringname,intage){}// 使用varpersonnewPerson(Alice,30);System.out.println(person.name());// 访问器方法自动生成System.out.println(person.age());6. 密封类Sealed ClassesJEP 360 → JEP 397 → JEP 409密封类允许开发者限制哪些类可以继承或实现某个类/接口提供更精细的继承控制。项目内容首次引入预览JDK 15JEP 360第二次预览JDK 16JEP 397正式定稿JDK 17JEP 409官方文档Sealed Classes// 定义一个密封类 Shape只允许 Circle 和 Rectangle 继承publicabstractsealedclassShapepermitsCircle,Rectangle{// ...}publicfinalclassCircleextendsShape{privatefinaldoubleradius;publicCircle(doubleradius){this.radiusradius;}publicdoubleradius(){returnradius;}}publicfinalclassRectangleextendsShape{privatefinaldoublewidth,height;publicRectangle(doublewidth,doubleheight){this.widthwidth;this.heightheight;}publicdoublewidth(){returnwidth;}publicdoubleheight(){returnheight;}}// Triangle 尝试继承 Shape → 编译错误publicfinalclassTriangleextendsShape{}// Compile error注意密封类与 Switch 表达式配合使用时若 Switch 模式匹配见第 7 节处于预览状态代码需要--enable-preview参数才能编译和运行。以下示例综合了两项特性// 需要 JDK 17 --enable-preview因为 Switch 模式匹配为预览特性doubleareaswitch(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 21JEP 441。本博客以 JDK 17 LTS 为核心但为了展示语法演进全貌特此收录。以下代码示例基于 JDK 17 预览版编写必须配合--enable-preview参数使用。项目内容首次引入预览JDK 17JEP 406第二次预览JDK 18JEP 420第三次预览JDK 19JEP 427第四次预览JDK 20JEP 433正式定稿JDK 21JEP 441—注超出 JDK 17 范围官方文档Pattern Matching for Switch// JDK 17预览支持类型模式和守卫模式Stringformattedswitch(obj){caseIntegerii10-String.format(大整数 %d,i);caseIntegeri-String.format(小整数 %d,i);caseLongl-String.format(长整数 %d,l);casenull-null;default-obj.toString();};8. 接口私有方法JEP 213——Milling Project CoinJDK 9 允许在接口中定义private方法用于在default方法之间共享公共代码。该特性直接定稿无预览阶段。项目内容首次引入正式定稿JDK 9JEPJEP 213: Milling Project Coin官方文档Java Language Changes for Java SE 9publicinterfaceCalculator{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)?ab:a-b;}}二、API 与库更新篇9. 工厂方法创建不可变集合JEP 269JDK 9 为List、Set、Map提供了便捷的静态工厂方法快速创建不可变集合。该特性直接定稿无预览阶段。项目内容首次引入正式定稿JDK 9JEPJEP 269: Convenience Factory Methods for Collections// JDK 8 写法ListStringlistnewArrayList();list.add(a);list.add(b);list.add(c);listCollections.unmodifiableList(list);// JDK 9 写法ListStringlistList.of(a,b,c);SetStringsetSet.of(x,y,z);MapString,IntegermapMap.of(key1,1,key2,2);10. 增强的伪随机数生成器JEP 356 → JEP 371JDK 17 引入了新的伪随机数生成器 APIRandomGenerator接口提供了更强大、更灵活的随机数生成能力。注意该 API 在 JDK 17 中为预览特性。项目内容首次引入预览JDK 17JEP 356正式定稿JDK 18JEP 371官方文档JDK 17 Release Notes// 旧方式RandomrandomnewRandom();intvaluerandom.nextInt(100);// JDK 17预览新方式JDK 18 正式可用RandomGeneratorgeneratorRandomGenerator.of(L128X1024MixRandom);intvaluegenerator.nextInt(100);11. 有用的 NullPointerExceptionJEP 358JDK 14 开始NullPointerException会精确指出哪个变量为null极大提升了调试效率。该特性直接定稿无预览阶段。项目内容首次引入正式定稿JDK 14JEPJEP 358: Helpful NullPointerExceptions// 代码a.b.c.i99;// JDK 8 的异常信息Exceptionin threadmainjava.lang.NullPointerExceptionatTest.main(Test.java:3)// JDK 14 的异常信息精确指出 null 的位置Exceptionin threadmainjava.lang.NullPointerException:Cannotread fieldcbecausea.bisnullatTest.main(Test.java:3)12. JShell——REPL 工具JEP 222JDK 9 引入了 JShell一个交互式的 Java REPLRead-Eval-Print Loop工具允许开发者在不编写完整类的情况下快速测试代码片段。该特性直接定稿无预览阶段。项目内容首次引入正式定稿JDK 9JEPJEP 222: JShell: The Java Shell$ jshell|欢迎使用 JShell -- 版本17|要大致了解该版本请键入/help intro jshellvar listList.of(1,2,3)list[1,2,3]jshelllist.stream().map(n -n *2).toList()$2[2,4,6]三、性能与运行时篇13. Java 平台模块系统Project JigsawJEP 261JDK 9 最重大的变化——模块化系统JPMS将 JDK 本身模块化并允许开发者创建自己的模块。该特性直接定稿无预览阶段。项目内容首次引入正式定稿JDK 9JEPJEP 261: Module System官方文档Project Jigsaw// module-info.javamodulecom.example.myapp{requiresjava.sql;requireshu.advancedweb.somedependency;exportscom.example.myapp.api;}14. ZGC——可扩展的低延迟垃圾回收器JEP 333 → JEP 377ZGC 是一种可扩展的低延迟垃圾回收器暂停时间不超过 10 毫秒且不随堆大小增加而增加。项目内容首次引入实验性JDK 11JEP 333正式产品化JDK 15JEP 377官方文档ZGC: The Z Garbage Collector# 启用 ZGC需显式指定java-XX:UseZGC-jarmyapp.jar关于“默认”的澄清JDK 17默认增强了对 ZGC 和 Shenandoah 的支持如性能优化和平台兼容性提升但垃圾回收器本身并未默认启用。开发者仍需通过-XX:UseZGC显式开启方可实现毫秒级停顿。15. 强封装 JDK 内部 APIJEP 403从 JDK 17 开始JDK 内部 API如sun.misc.Unsafe被默认强封装应用程序无法再通过反射随意访问。项目内容首次引入正式定稿JDK 17JEPJEP 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 默认 denyJDK 18 报错java--illegal-accesspermit-jarmyapp.jar# 推荐方式精确开放特定包java--add-opens java.base/java.langALL-UNNAMED-jarmyapp.jar四、各版本 JEP 数量一览版本发布时间是否 LTS主要 JEP 数量JDK 82014.03✅ LTS56JDK 92017.09❌—JDK 102018.03❌—JDK 112018.09✅ LTS17JDK 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 Summaryhttps://docs.oracle.com/en/java/javase/17/language/java-language-changes-summary.htmlJava SE 17 规范JSR 392https://cr.openjdk.java.net/~iris/se/17/latestSpec/JDK 17 Release Noteshttps://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 了——这不仅是一次版本升级更是一次开发范式的跃迁。
返回列表