目录

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:
https://i-blog.csdnimg.cn/direct/8a61c2d451f54c2f8cf4fbcc419de6ef.png

密封类

密封类⼀般应⽤在类和接⼝中,对接⼝和类的实现和继承进⾏约束。主要使⽤的关键字是 final 。当这个类被 final 修饰了,被修饰的类就变成完全封闭的状态了,所有类都没办法继承。
JDK17提供了⼀个新的关键字: sealed .密封类除了可以被该关键字修饰,并且在声明末尾⽤permits 表⽰要开放给哪些类型。
下述代码Animal 为密封类,然后使⽤ permits 关键字,把继承权限开放 给了Dog 类
首先:
https://i-blog.csdnimg.cn/direct/8da092fd80534482b91fc68707df9bd6.png

https://i-blog.csdnimg.cn/direct/d3d7f133666c4d0db820dfd9cdb22b31.png
这里很有意思,给Dog加了sealed还是报错了。
刚才不是还说“继承的类也需要被密封,可以使用final,sealed,non-sealed。”吗?注意,这个时候报错原因不一样了,因为Dog也被sealed修饰了,所以也需要子类。或者改成non-sealed或者final。

重点总结:

  1. sealed修饰的类必须要有⼦类
  2. 使⽤ non-sealed 关键字修饰。表⽰不限制,任何类都可以继承。
  3. 未被 permits 允许的类型,则没办法继承。
    注意,前面的几段代码都没有加permits,此时任何类都可以继承,但是加了permits之后只有被permits修饰的类才可以继承。
    https://i-blog.csdnimg.cn/direct/2546407d8d7b4be884c187a21b54d870.png
  4. 复杂的特殊写法
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 使用经验,一起交流学习~