本文主要介绍一些在JDK17中新增的一些语法特性。
目录
前言
从SpringBoot3.0开始,已经不再支持JDK8了,从3.0开始,转变为了JDK17。参考资料,来自官方博客:https://spring.io/blog/2022/01/20/spring-boot-3-0-0-m1-is-now-available?spm=a2c6h.12873639.article-detail.24.766d46b40LM1IV

官方的维护版本都是SpringBoot3.x的了,但是之前的版本也是可以用的,只是官方不再进行版本更新了。
总的来说,选用Java 17,概括起来有三个主要原因:JDK17是LTS,也就是长期支持版,可以免费商用到2029年,而且将前面几个过渡版去其糟粕取其精华;JDK 17的性能提升不少,比如重写了底层NIO,至少提升了10%起步;大多数第三方框架和库都已经支持,不会有什么大坑。
一、yield关键字
我们在正常去使用switch-case结构的时候是这样操作的:
java
public class Main {
public static void main(String[] args) {
String data = "one";
int result;
switch(data) {
case "one":
result = 1;
break;
case "two":
result = 2;
break;
default:
result = -1;
break;
}
System.out.println(result);
}
}
我们可以用如下的语法形式来简化switch结构:
java
public class Main {
public static void main(String[] args) {
String data = "one" ;
int result = switch (data) {
case "one"->1;
case "two"->2;
default->-1;
};
System.out.println(result) ;
}
}
在Java13开始,我们引入了yield关键字,它也可以用于从case的代码块中返回值,它主要就是替换了我们上面这种形势之中出现的->运算符。比如如下的代码形式:
java
public class Main {
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关键字
从Java 10开始,我们引入了var关键字,比如如下的代码:
java
var name = "zhangsan";
var age = 10;
上述代码中,编译器会自动推断出name是⼀个String类型,age是⼀个int类型。那么我们为什么要使用var?一个主要的原因就是使用var可以使代码更简洁。有时候,类型名称可能会非常长,例如泛型。var就像是⼀个简化器,让我们不必反复写出繁琐的类型名。比如说下面这样:
java
public static void main(String[] args) {
Map<String, List<Map<Integer, String>>> complexMap = new HashMap<String,
List<Map<Integer, String>>>();
var complexMap2 = new HashMap<String, List<Map<Integer, String>>>();
}
但在使用var的时候,我们要注意如下的问题,不能使用var来声明字段,不能使用var来声明方法参数,不能使用var来声明方法返回类型,var声明变量必须初始化,但是不能初始化为null。也就是如下的情况都是对于var的错误使用:
java
class OrgCat {
public var name;//error
public var eat(var str) {//error
}
}
public static void main(String[] args) {
var complexMap2 = 10;
System.out.println(complexMap2);
var str = null;//error
}
三、空指针异常
出现异常的具体方法和原因都⼀目了然。如果你的⼀行代码中有多个方法、多个变量,可以快速定位问题所在,如果是JDK1.8,有些情况下真的不太容易看出来。比如JDK8,就是下面这种报错:

而JDK17的话,就是下面这种:

四、密封类
密封类⼀般应用在类和接口中,对接口和类的实现和继承进行约束。主要使用的关键字是final。当
这个类被final修饰了,被修饰的类就变成完全封闭的状态了,所有类都没办法继承。JDK17提供了⼀个新的关键字sealed,密封类除了可以被该关键字修饰,并且在声明末尾用permits表示要开放给哪些类型。下面这段代码Animal为密封类,然后使用permits关键字,把继承权限开放给了Dog 类:
java
sealed class Animal permits Dog{
public String name;
public int age;
public void eat() {
System.out.println("eat()....");
}
}
non-sealed class Dog extends Animal{
@Override
public void eat() {
System.out.println(this.name+ "正在吃狗粮....");
}
}
总的来说,其有如下需要注意的部分。首先是sealed修饰的类必须要有子类,否则就会报错,比如下面的代码,就会提示我们Sealed class must have subclasses的信息:
java
sealed class Animal {
public String name;
public int age;
public void eat() {
System.out.println("eat()....");
}
}
sealed class Dog extends Animal{
@Override
public void eat() {
System.out.println(this.name+ "正在吃狗粮....");
}
}
其次我们如果使用non-sealed关键字来修是的话就表示不限制,任何类都可以来继承,比如最开始的代码。然后如果我们的类型未被permits关键字允许,则我们就没办法去继承:
java
sealed class Animal permits Dog {
public String name;
public int age;
public void eat() {
System.out.println("eat()....");
}
}
non-sealed class PetDog extends Animal {
}
上面的代码可以更改为如下部分:
java
sealed class Animal permits Dog,PetDog {
public String name;
public int age;
public void eat() {
System.out.println("eat()....");
}
}
non-sealed class Dog extends Animal {
@Override
public void eat() {
System.out.println(this.name+ "正在吃狗粮....");
}
}
non-sealed class PetDog extends Animal {
}
五、接口中的私有方法
Java 8中接口可以有默认方法。Java 9之后,可以在接口内实现私有方法实现。比如下面的代码:
java
interface HelloService {
public void sayHello();
// 默认⽅法
default void saySomething(){
syaEngHello();
sayHello();
};
// 私有⽅法
private void syaEngHello(){
System.out.println("Hello!");
}
}
六、instanceof
我们之前使用instanceof关键字进行过如下的操作:
java
if (obj instanceof String) {
String str = (String) obj;
...
}
上面的instancof语法⼀共做了三件事,判断是否为String类型;如果是,转成String类型;创建⼀个名为str 的临时变量。在JDK16中,使用模式匹配思想改进了instanceof用法,可以做到以下优化效果:
java
if (obj instanceof String str) {// obj是否为String类型,如果是创建临时变量str
}
七、其他
其他还有很多未列举到的,比如下面这些:
-
ZGC-新⼀代垃圾回收器、G1垃圾回收器相关等等
-
record 类的使用
-
Stream API的部分改进
-
HttpClient 重写了,支持 HTTP2.0
-
支持 List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法实例化对象
等等等等很多的知识,之后遇到我们再行介绍。
总结
本文介绍了JDK17中的主要新特性:switch表达式支持yield返回值,简化了switch-case结构;var关键字支持局部变量类型推断,提升代码简洁性;改进了空指针异常提示,使问题定位更清晰;新增sealed密封类,通过permits精确控制继承权限;接口支持私有方法实现;instanceof模式匹配简化类型判断和转换。这些改进使Java代码更简洁、安全,同时提升了开发效率和性能。JDK17作为长期支持版本,是企业级应用的理想选择。