JDK新特性

版本分类

1. 版本分类与发布周期

LTS 版本:每 2 年发布一次,提供长期维护和安全更新支持,是企业级应用的首选。截至 2025 年 7 月 24 日,最新 LTS 版本为JDK 21(2023 年 9 月发布),历史重要 LTS 版本包括 JDK 8、11、17。

非 LTS 版本:每 6 个月发布一次,包含最新特性但支持周期短(通常仅 6 个月),适合追求新功能的开发者或测试场景。截至 2025 年 7 月 24 日,最新非 LTS 版本为JDK 24。

2.各版本发布与停止支持时间(部分关键版本)

GA 版本

发布日期

停止支持日期(EOSL)

版本类型

JDK 8 LTS

2014 年 03 月 18 日

2030 年 12 月

LTS

JDK 9

2017 年 09 月 21 日

2018 年 03 月

非 LTS

JDK 11 LTS

2018 年 09 月 25 日

2026 年 09 月

LTS

JDK 17 LTS

2021 年 09 月 14 日

2029 年 09 月

LTS

JDK 21 LTS

2023 年 09 月 19 日

2031 年 09 月

LTS

JDK 24

2025 年(推测)

2025 年(推测,6 个月后)

非 LTS

3.2024 年 JDK 用户占比

JDK 17:35%

JDK 11:33%

JDK 8:29%

其他版本(如 JDK 21 等):3%

现状:尽管新版本不断推出,JDK 8 仍被多数企业采用,但 JDK 17、11 的占比正逐步提升。

JEP

1. JEP 定义

JEP(JDK Enhancement Proposals)即 JDK 增强提案,是 Java 平台新功能或重大改进的 “提案说明书”,涵盖功能描述、设计思路、实现方式、影响范围及与现有 Java 生态的关系等内容。

2.JEP 分类及示例

JEP 类型

示例

适用人群 / 场景

语言特性

switch 表达式、模式匹配、Record 类

所有 Java 开发者,日常编码高频使用

JVM 改进

ZGC、Shenandoah、分段编译

JVM 工程师、性能调优人员

API 增强

Stream、Collectors、集合增强

所有 Java 开发者,提升编码效率

工具改进

jshell、jpackage、jfr

开发 / 测试人员,辅助开发测试

架构调整

模块化系统(JPMS)、孵化器模块

架构师、大型项目开发团队

3.学习原则

无需学习所有 JEP:部分 JEP 属于底层优化(如 JVM 垃圾回收改进)或实验性内容,与多数开发者日常工作无关。

重点学习方向:聚焦与工作相关的 API 增强、语言特性类 JEP;关注已稳定、可用于生产环境的 JEP,避免依赖实验性 JEP。

各版本核心新特性

1. JDK 9 新特性

(1)JPMS 模块化(Project Jigsaw)

背景:解决传统 JAR 方式的臃肿、内部 API 暴露、依赖复杂等问题(如 rt.jar 全量加载导致性能负载)。

核心优势:

性能提升:仅加载运行所需模块,加快启动速度。

增强封装:通过exports指令控制对外暴露的包,隐藏内部实现。

提升安全性:减少潜在攻击面。

关键指令:

requires:声明当前模块依赖的其他模块(如requires ModuleA;)。

exports:声明当前模块对外暴露的包(如exports com.briup.utils;),支持exports ... to ...指定暴露对象。

requires transitive:实现依赖传递(如requires transitive java.sql;)。

open/opens:解决反射访问私有包的问题(如open module ModuleA;)。

注意事项:module-info.java必须放在 src 目录下;依赖模块包名不可重复。

(2)交互式编程(JShell)

定义:Java 的 REPL(Read-Eval-Print Loop)环境,支持直接输入代码片段并即时查看结果,无需编写完整类 / 方法。

基础功能:执行表达式(如2 + 3)、定义变量 / 方法 / 类、查看定义内容(/vars//methods//types)、保存 / 加载代码(/save//open)。

(3)其他重要特性

接口私有方法--> 支持普通私有方法和静态私有方法,增强接口封装性,减少代码重复(如抽取公共逻辑)

钻石操作符增强--> 匿名类中支持<>,编译器自动推断泛型类型(如Comparator<>())

资源释放优化--> try-with-resources 支持已定义的资源对象(如try (fis; fos) {...})

String 底层改进--> 由char[]改为byte[] + coder,纯 ASCII 字符串内存消耗减少一半

集合 of 方法--> 静态工厂方法List.of()/Set.of()/Map.of(),快速创建不可变集合

Stream API 新增方法--> 新增takeWhile(保留满足条件元素至不满足)、dropWhile(跳过满足条件元素)等 4 个方法

2. JDK 10 新特性

(1)局部变量类型推断

核心功能:用var关键字声明局部变量,编译器根据初始化表达式自动推断类型(如var name = "Tom";推断为 String)。

适用场景:局部变量声明(如循环变量、集合遍历变量)、简化复杂泛型声明(如var entrySet = map.entrySet();)。

限制场景:不可用于成员变量、方法参数、方法返回值;变量必须初始化;不可用于数组静态初始化(如var arr = {1,2,3}错误)。

(2)新增 API

集合copyOf()--> List.copyOf()/Set.copyOf()/Map.copyOf(),创建不可变集合副本

IO 流transferTo()--> InputStream/Reader 的该方法可直接将数据传输到输出流,简化文件拷贝

Charset 参数构造函数--> InputStreamReader/OutputStreamWriter 支持指定 Charset(如StandardCharsets.UTF_8)

ByteArrayOutputStreamtoString(Charset)--> 按指定字符集将缓冲区内容转为字符串,避免编码问题

3. JDK 11 新特性(LTS 版本)

(1)String 新增方法

方法名

功能描述

示例

isBlank()

判断字符串是否为空白(含空格、制表符、换行符)

" \t \n ".isBlank() → true

strip()

移除首尾所有空格(含 Unicode 空格),区别于trim()(仅处理 ASCII 空格)

" Hello ".strip() → "Hello"

repeat(int n)

将字符串重复 n 次

"Java".repeat(3) → "JavaJavaJava"

lines()

将字符串按行分割为 Stream,用于统计行数或处理每行内容

"A\nB\nC".lines().count() → 3

(2)HTTP Client(标准 API)

替代对象:取代旧的HttpURLConnection API。

核心优势:支持同步 / 异步请求、HTTP/2 协议、WebSocket;API 更简洁,减少样板代码。

示例:同步请求通过client.send(),异步请求通过client.sendAsync()返回CompletableFuture。

(3)局部类型推断改进

支持在 lambda 表达式形参中使用var,并可添加注解(如(@NotNull var text) -> {...}),提升代码清晰度与静态分析能力。

4. JDK 12 - 17 新特性

(1)switch 表达式增强

JDK 12(预览):支持多 case 合并(如case 12, 1, 2 -> "冬季"),无需break,直接返回值。

JDK 13(预览):新增yield语句,支持在代码块中返回值(如case 6,7,8 -> { yield "夏季"; })。

JDK 14(正式):成为标准特性,彻底替代传统 switch 的冗长写法。

(2)文本块(Text Blocks)

JDK 13(预览)- JDK 15(正式):用"""界定多行字符串,无需\n或+拼接,自动调整缩进(如 HTML/XML/SQL 语句编写)。

示例:

String html = """

<html>

  <body>

    <p>Hello</p>

  </body>

</html>

""";

(3)instanceof 模式匹配

JDK 16(正式):instanceof检查通过后自动完成类型转换,减少显式转换代码(如if (obj instanceof String str) { str.length(); })。

JDK 17 + 扩展:支持在 switch 中使用(如case Circle c -> System.out.println(c.radius());)。

(4)Record 类

JDK 16(正式):不可变数据载体类,自动生成全参构造、equals()/hashCode()/toString()、属性 getter(如Person(String name, int age)自动生成name()/age())。

限制:类默认 final,不可继承;属性默认 final,无 setter;不可定义实例字段(可定义静态字段 / 方法)。

(5)密封类(Sealed Classes)

JDK 17(正式):用sealed关键字定义,指定允许继承 / 实现的子类 / 实现类(如sealed interface Shape permits Circle, Rectangle),控制类层次结构。

子类约束:子类需为final(不可继承)、sealed(继续限制)或non-sealed(取消限制,可自由继承)。

关键问题

问题 1:企业在选择 JDK 版本时,应优先考虑 LTS 版本还是非 LTS 版本?依据是什么?

答案:

企业应优先选择 LTS 版本,依据如下:

支持周期:LTS 版本支持周期极长(如 JDK 8 支持至 2030 年、JDK 17 支持至 2029 年),能为企业级应用提供长期的安全更新和维护,避免频繁升级版本带来的成本;非 LTS 版本仅支持 6 个月,需快速跟进新版本,稳定性和维护性不足。

生态兼容性:多数企业级框架(如 Spring Boot、MyBatis)会优先适配 LTS 版本,确保功能稳定运行;非 LTS 版本的新特性可能未被框架完全兼容,存在潜在风险。

用户基础:2024 年数据显示,JDK 8(35%)、11(33%)、17(29%)三大 LTS 版本占据 97% 的用户市场,社区资源丰富,遇到问题时易获取解决方案;非 LTS 版本用户占比低,问题排查难度更高。

例外场景:若企业需验证某非 LTS 版本的特定新特性(如 JDK 20 的某实验性 API),可在测试环境使用,但生产环境仍需回归 LTS 版本。

问题 2:JDK 9 的 JPMS 模块化解决了传统 JAR 包方式的哪些核心问题?实际开发中配置模块化需注意哪些关键点?

答案:

1. JPMS 模块化解决的传统 JAR 包核心问题

环境臃肿与性能问题:传统 JAR 包需全量加载(如 rt.jar),即使应用仅用部分类,也会增加 JVM 内存负载和启动时间;模块化支持 “按需加载”,仅加载运行所需模块,提升性能。

内部 API 暴露问题:传统方式依赖权限修饰符(public/private)封装,无法隐藏整个包,内部实现易被外部访问 / 修改;模块化通过exports指令精确控制暴露的包,未导出包完全隐藏。

依赖管理复杂问题:大型项目中 JAR 包依赖易出现版本冲突、重复依赖;模块化通过requires指令明确依赖关系,减少依赖混乱。

安全性问题:传统方式难以控制库的访问权限,可能因内部 API 被滥用导致安全漏洞;模块化限制包可见性,减少潜在攻击面。

2. 实际开发配置模块化的关键点

配置文件位置:module-info.java必须放在模块的 src 目录根路径下,否则 JVM 无法识别模块结构。

包名唯一性:依赖模块与被依赖模块的包名不可重复(如 ModuleA 和 ModuleB 均含com.briup.test包,会导致运行报错)。

依赖传递控制:若需让依赖模块的依赖对当前模块可见,需用requires transitive(如requires transitive java.sql;),普通requires无法实现依赖传递。

反射访问处理:若外部模块需通过反射访问当前模块的私有包,需用open(开放整个模块)或opens(开放指定包)指令(如opens com.briup.model to ModuleB;)。

编译版本适配:模块化仅支持 JDK 9 及以上版本,需确保项目编译版本设置为-source 9或更高(如 IDEA 中配置 “Project bytecode version” 为 9+)。

问题 3:JDK 8 到 JDK 17 的 String 类有哪些重要改进?这些改进对实际开发有哪些影响?

答案:

1. JDK 8 到 JDK 17 String 类的重要改进

JDK 9底层存储结构优化--> 由private final char[] value改为private final byte[] value + private final byte coder,coder标识编码(1 字节 / 2 字节)

JDK 11新增实用方法--> 新增isBlank()、strip()、stripLeading()、stripTrailing()、repeat(int)、lines()6 个方法

2. 改进对实际开发的影响

JDK 9 底层优化的影响:

内存节省:对于纯 ASCII 字符串(如英文、数字),存储由 2 字节 / 字符降至 1 字节 / 字符,内存消耗减少 50%,尤其适合处理大量文本数据的应用(如日志系统、文本解析工具),能显著降低 JVM 内存占用。

性能平衡:虽字符访问时需通过coder判断编码,增加轻微性能开销,但因内存占用减少,缓存命中率提升,大型应用的整体执行速度通常会提高。

兼容性保障:底层结构变化完全透明,上层 API(如length()、charAt())无任何改变,现有 String 相关代码无需修改即可兼容 JDK 9+。

JDK 11 新增方法的影响:

简化字符串操作:减少样板代码,如判断空白字符串无需再写str.trim().isEmpty(),直接用str.isBlank();重复字符串无需循环拼接,用str.repeat(n)即可。

处理多语言空格:strip()系列方法支持 Unicode 空格(如中文全角空格),trim()仅处理 ASCII 空格,避免因多语言空格导致的逻辑错误(如用户输入含全角空格时,trim()无法识别)。

便捷文本处理:lines()方法将字符串按行分割为 Stream,便于处理多行文本(如统计日志行数、按行过滤内容),结合 Stream API 可简化代码(如str.lines().filter(line -> line.contains("error")).count()统计错误日志行数)。

提升代码可读性:新增方法语义更清晰(如repeat(3)比循环拼接更易理解),降低代码维护成本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值