首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【jdk】JDK17语法新增特性

【jdk】JDK17语法新增特性

作者头像
那我掉的头发算什么
发布2026-01-12 18:19:42
发布2026-01-12 18:19:42
1870
举报

大家好!随着 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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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来代替:

代码语言:javascript
复制
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,编译器会根据初始化值自动推断变量类型,尤其适合长泛型类型,减少代码冗余。

代码语言:javascript
复制
var name = "zhangsan"; // 推断为String
var age = 10;          // 推断为int
var list = new ArrayList<String>(); // 推断为ArrayList<String>

编译器自动推断!

传统泛型声明需重复写复杂类型,var可简化:

代码语言:javascript
复制
// 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)

代码语言:javascript
复制
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:

在这里插入图片描述
在这里插入图片描述

JDK17:

在这里插入图片描述
在这里插入图片描述

出现异常的具体⽅法和原因都⼀⽬了然。如果你的⼀⾏代码中有多个⽅法、多个变量,可以快速定位问题所在,如果是 JDK1.8,有些情况下真的不太容易看出来。

密封类

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

在这里插入图片描述
在这里插入图片描述

如果只是sealed修饰一个类,但这个类没有子类会报错。

在这里插入图片描述
在这里插入图片描述

但是继承的类也需要被密封,可以使用final,sealed,non-sealed。

在这里插入图片描述
在这里插入图片描述

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

重点总结:

  1. sealed修饰的类必须要有⼦类
  2. 使⽤ non-sealed 关键字修饰。表⽰不限制,任何类都可以继承。
  3. 未被 permits 允许的类型,则没办法继承。 注意,前面的几段代码都没有加permits,此时任何类都可以继承,但是加了permits之后只有被permits修饰的类才可以继承。
在这里插入图片描述
在这里插入图片描述
  1. 复杂的特殊写法
代码语言:javascript
复制
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 继承该特性)支持接口定义私有实例方法和私有静态方法,用于封装接口内部复用逻辑。

代码语言:javascript
复制
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,支持类型判断 + 强制转换 + 变量声明一步完成,避免传统写法的冗余。

代码语言:javascript
复制
public void handleObj(Object obj) {
    // 1. 判断类型 → 2. 强制转换 → 3. 声明变量
    if (obj instanceof String) {
        String str = (String) obj; // 冗余:重复String类型
        System.out.println("字符串长度:" + str.length());
    }
}
代码语言:javascript
复制
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 使用经验,一起交流学习~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • yield关键字
  • var关键字
  • 空指针异常
  • 密封类
  • 接口中的私有方法
  • instanceof
  • 其他实用特性(简要盘点)
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档