jdkJDK17语法新增特性
【jdk】JDK17语法新增特性
大家好!随着 Spring Boot 3.0 正式放弃对 JDK 8 的支持,转向 JDK 17 作为默认依赖(Spring 官方公告),JDK 17 已经成为企业级开发的 “标配”。作为长期支持版(LTS),它不仅能免费商用至 2029 年,还整合了 JDK 9-16 的精华特性,同时带来至少 10% 的性能提升(如底层 NIO 重写),且主流框架已全面兼容。
今天就带大家梳理 JDK 17 中最常用的语法新特性,结合代码示例帮你快速上手!
yield关键字
在 JDK 13 之前,switch 语句需要通过break控制流程,返回值需额外定义变量;JDK 13 引入yield后,可直接在 case 块中返回值,配合箭头语法进一步简化代码。
正常switch:
public static void main1(String[] args) {
String data = "one" ;
int result = 0 ; // 接收数据的返回值
switch (data) {
case "one":
result = 1 ; // 为result重新赋值
break ;
case "two":
result = 2 ; // 为result重新赋值
break ;
default:
result = -1 ; // 为result重新赋值
break ;
}
System.out.println(result) ;
}
正常简化版switch:
public static void main2(String[] args) {
String data = "one";
int result = switch(data){
case "one"->1;
case "two"->2;
default ->1;
};
System.out.println(result);
}
如果不想使⽤指向符-> 可以使⽤yield来代替:
public static void main(String[] args) {
String data = "one";
int result = switch (data){
case "one" : yield 1;
case "two" : yield 2;
default : yield -1;
};
System.out.println(result);
}
var关键字
JDK 10 引入var,编译器会根据初始化值自动推断变量类型,尤其适合长泛型类型,减少代码冗余。
var name = "zhangsan"; // 推断为String
var age = 10; // 推断为int
var list = new ArrayList<String>(); // 推断为ArrayList<String>
编译器自动推断!
传统泛型声明需重复写复杂类型,var可简化:
// JDK 8风格:类型重复,冗余
Map<String, List<Map<Integer, String>>> complexMap = new HashMap<String, List<Map<Integer, String>>>();
// JDK 10+:var自动推断,简洁
var complexMap2 = new HashMap<String, List<Map<Integer, String>>>();
var的限制⭐⭐⭐
不能修饰类字段(成员变量)
不能修饰方法参数
不能修饰方法返回值
声明时必须初始化(且不能初始化为null)
class Demo {
// 错误:var不能修饰字段
public var name;
// 错误:var不能修饰方法参数
public void eat(var food) {}
// 错误:var不能修饰返回值
public var getAge() { return 18; }
public static void main(String[] args) {
var num = 10; // 正确:初始化非null
// 错误:var不能初始化为null(无法推断类型)
var str = null;
}
}
空指针异常
JDK8:
密封类
密封类⼀般应⽤在类和接⼝中,对接⼝和类的实现和继承进⾏约束。主要使⽤的关键字是 final 。当这个类被 final 修饰了,被修饰的类就变成完全封闭的状态了,所有类都没办法继承。
JDK17提供了⼀个新的关键字: sealed .密封类除了可以被该关键字修饰,并且在声明末尾⽤permits 表⽰要开放给哪些类型。
下述代码Animal 为密封类,然后使⽤ permits 关键字,把继承权限开放 给了Dog 类
首先:
这里很有意思,给Dog加了sealed还是报错了。
刚才不是还说“继承的类也需要被密封,可以使用final,sealed,non-sealed。”吗?注意,这个时候报错原因不一样了,因为Dog也被sealed修饰了,所以也需要子类。或者改成non-sealed或者final。
重点总结:
- sealed修饰的类必须要有⼦类
- 使⽤ non-sealed 关键字修饰。表⽰不限制,任何类都可以继承。
- 未被 permits 允许的类型,则没办法继承。
注意,前面的几段代码都没有加permits,此时任何类都可以继承,但是加了permits之后只有被permits修饰的类才可以继承。 - 复杂的特殊写法
sealed class Animal permits Dog,Cat {
public String name;
public int age;
public void eat() {
System.out.println("eat()....");
}
}
sealed class Cat extends Animal permits OrgCat{
}
non-sealed class OrgCat extends Cat {
}
接口中的私有方法
DK 8 允许接口有default方法(带默认实现),但无法定义私有方法;JDK 9+(JDK 17 继承该特性)支持接口定义私有实例方法和私有静态方法,用于封装接口内部复用逻辑。
interface HelloService {
// 抽象方法(必须实现)
void sayHello();
// 默认方法(可直接调用私有方法)
default void sayFullHello() {
sayEnglishHello(); // 调用私有方法
sayHello(); // 调用抽象方法
}
// 私有实例方法(仅接口内部可用)
private void sayEnglishHello() {
System.out.println("Hello!");
}
// 私有静态方法(接口内部可用,可通过接口名调用)
private static void log() {
System.out.println("调用日志:sayFullHello执行");
}
}
// 实现类
class ChineseHello implements HelloService {
@Override
public void sayHello() {
System.out.println("你好!");
}
public static void main(String[] args) {
HelloService hello = new ChineseHello();
hello.sayFullHello();
}
}
instanceof
JDK 16+(JDK 17 包含)优化了instanceof,支持类型判断 + 强制转换 + 变量声明一步完成,避免传统写法的冗余。
public void handleObj(Object obj) {
// 1. 判断类型 → 2. 强制转换 → 3. 声明变量
if (obj instanceof String) {
String str = (String) obj; // 冗余:重复String类型
System.out.println("字符串长度:" + str.length());
}
}
public void handleObj(Object obj) {
// 一步完成:判断类型 + 声明变量(str自动为String类型)
if (obj instanceof String str) {
System.out.println("字符串长度:" + str.length());
}
}
其他实用特性(简要盘点)
除了上述核心语法,JDK 17 还有不少提升开发效率的特性:
ZGC 垃圾回收器:低延迟(毫秒级停顿),支持 TB 级内存,大幅提升大型应用性能;
Record 类:简化 “数据载体类”(如 POJO),自动生成equals()、hashCode()、toString()等方法;
Stream API 增强:新增toList()方法,简化流结果收集(stream().toList()替代Collectors.toList());
HttpClient 升级:重写底层,支持 HTTP/2 和 WebSocket,替代老旧的HttpURLConnection;
集合工厂方法:List.of()、Set.of()、Map.of()快速创建不可变集合(简化new ArrayList<>()等写法)。
总结
JDK 17 作为 LTS 版本,不仅是 Spring Boot 3.x 的 “标配”,更通过语法简化(var、yield、instanceof)、继承控制(密封类)、错误定位优化(NPE)等特性,大幅提升开发效率和代码质量。
如果你还在使用 JDK 8,建议逐步升级到 JDK 17—— 毕竟免费商用至 2029 年,且主流框架已全面兼容,早升级早享受这些便捷特性!
欢迎在评论区分享你的 JDK 17 使用经验,一起交流学习~