网易首页 > 网易号 > 正文 申请入驻

JDK17 神仙语法让代码优雅到飞起

0
分享至

Java精选面试题(微信小程序):5000+道面试题和选择题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计、大厂真题等,在线随时刷题!

从优雅的密封类到简洁的记录类,从模式匹配到文本块,这些"神仙语法"不仅能让你的代码行数减少 30%,还能提高代码可读性和维护性。作为一位使用 JDK 17 已有两年的开发者,我将分享这些强大特性如何在实际项目中为我节省了无数时间,并彻底改变了我编写 Java 代码的方式。准备好迎接 Java 的新时代了吗?

一、从JDK8到JDK17
为什么 JDK 17 是里程碑版本

JDK 17 不仅仅是一个普通的版本更新,它标志着 Java 平台的重大转变。作为继 JDK 8 和 JDK 11 之后的又一个长期支持(LTS)版本,JDK 17 集成了自 JDK 9 以来的所有创新特性,是 Java 现代化进程中的重要里程碑。

长期支持版本的意义

作为 LTS 版本,JDK 17 将获得至少 8 年的支持期。这意味着企业可以安心地将其应用迁移到 JDK 17 上,享受新特性带来的便利,同时不必担心频繁升级的问题。对于那些仍在使用 JDK 8 的开发者来说,直接跳到 JDK 17 是一个明智的选择。

二、记录类(Record)
传统 JavaBean 的痛点

在传统 Java 开发中,创建一个简单的数据类需要编写大量模板代码:

public class Person {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }
    public int getAge() { return age; }

    @Override
    public boolean equals(Object o) {
        // 长长的equals实现...
    }

    @Override
    public int hashCode() {
        // hashCode实现...
    }

    @Override
    public String toString() {
        return "Person[name=" + name + ", age=" + age + "]";
    }
}

这种冗长的代码不仅编写麻烦,而且容易出错,更重要的是它掩盖了类的本质意图。

Record 的基本语法与使用

JDK 17 中的记录类(Record)彻底解决了这个问题:

public record Person(String name, int age) {}

就这么简单!编译器会自动为你生成构造器、getter 方法、equals()、hashCode() 和 toString() 方法。这一行代码等同于前面的几十行代码,简直是偷懒神器!

Record 与不可变对象

Record 天生是不可变的,这符合函数式编程的理念,有助于编写线程安全的代码。如果你需要修改记录的某个字段,只能创建一个新的实例:

Person alice = new Person("Alice", 25)
// 想要修改年龄?创建一个新实例
Person olderAlice = new Person(alice.name(), alice.age() + 1)

何时使用与不使用 Record

Record 非常适合作为 DTO(数据传输对象)、值对象或不可变数据容器。但它也有局限性:不能继承其他类,不能声明实例字段(除了在构造函数中定义的),不能是抽象的。如果你需要这些特性,还是应该使用传统类。

三、密封类(Sealed Classes)
密封类的核心概念

在 Java 中,一个类要么是 final 的(不能被继承),要么可以被任何类继承。密封类(Sealed Classes)提供了一种中间状态:你可以指定哪些类可以继承它。

public sealed class Shape permits Circle, Rectangle, Triangle {
    // 共享方法和属性
}

permits 关键字详解

permits关键字明确列出了允许继承该密封类的所有子类。子类必须使用finalsealednon-sealed修饰符来声明自己的继承策略:

public final class Circle extends Shape {
    // Circle不能再被继承
}

public sealed class Rectangle extends Shape permits Square {
    // Rectangle只能被Square继承
}

public non-sealed class Triangle extends Shape {
    // Triangle可以被任何类继承
}

与接口结合使用

密封特性也适用于接口:

public sealed interface Vehicle permits Car, Truck, Motorcycle {
    void move();
}

实际应用案例

密封类非常适合领域建模,特别是当你有一个封闭的类型集合时:

public sealed interface PaymentMethod permits CreditCard, DebitCard, BankTransfer, DigitalWallet {
    boolean processPayment(double amount);
}

public final class CreditCard implements PaymentMethod {
    @Override
    public boolean processPayment(double amount) {
        // 信用卡支付逻辑
        return true;
    }
}

// 其他实现类...

这样,当你使用 switch 语句处理不同的支付方式时,编译器可以确保你已经处理了所有可能的情况。

四、模式匹配
类型模式匹配

在 JDK 17 之前,使用 instanceof 进行类型检查后,我们还需要显式地进行类型转换:

// 旧方式
if (obj instanceof String) {
    String s = (String) obj;
    if (s.length() > 5) {
        // 使用字符串 s
    }
}

JDK 17 引入了模式匹配,可以在 instanceof 中直接绑定变量:

// 新方式
if (obj instanceof String s && s.length() > 5) {
    // 直接使用字符串 s
}

简洁明了,一气呵成!

switch 表达式增强

JDK 17 中的 switch 也支持了模式匹配:

Object obj = getSomeObject();
String result = switch (obj) {
caseInteger i -> "整数: " + i;
caseString s -> "字符串: " + s;
casePerson p -> "人: " + p.name();
default -> "未知类型";
};

性能考量

模式匹配不仅提高了代码可读性,而且在许多情况下还能提升性能,因为编译器可以对模式匹配进行优化,减少冗余的类型检查。

五、文本块
传统字符串拼接的问题

在 JDK 15 之前,处理多行字符串是一件痛苦的事情:

String html ="\n"+
"    \n"+
"         Hello, World!\n"+
"    \n"+
"";

这种代码不仅难以维护,而且容易出错。

文本块语法详解

JDK 17 中的文本块(Text Blocks)让多行字符串变得简单:

String html = """
             
                 
                      Hello, World!
                 
             
              """

文本块以三个双引号开始和结束,中间的内容可以包含任意字符,包括换行符和引号,无需转义。

格式控制技巧

文本块会自动删除每行开头的公共空白,但你可以通过\s来保留空格,或使用 `` 来连接行:

String query = """
               SELECT id, name, email \
               FROM users \
               WHERE status = 'ACTIVE' \
               ORDER BY name"""

JSON、SQL 和 HTML 处理实例

文本块特别适合处理结构化文本:

// JSON示例
String jsonConfig = """
                    {
                        "appName": "神仙应用",
                        "version": "1.0.0",
                        "features": [
                            "记录类",
                            "密封类",
                            "模式匹配"
                        ]
                    }
                    """
// SQL示例
String sql = """
             SELECT p.name, p.age, a.city
             FROM persons p
             JOIN addresses a ON p.id = a.person_id
             WHERE a.country = '中国'
               AND p.age > 18
             """

六、var与增强型switch
类型推断的魅力

虽然var是在 JDK 10 中引入的,但它与 JDK 17 的其他特性结合使用时,可以让代码更加简洁:

// 不使用var
Map

 > groupedPeople = new HashMap<>(); // 使用var var groupedPeople = new HashMap

 >(); 


switch 表达式与 yield

JDK 17 中的 switch 可以作为表达式使用,并且可以直接返回值:

int dayOfWeek = 3;
String day = switch (dayOfWeek) {
case1 -> "星期一";
case2 -> "星期二";
case3 -> "星期三";
case4 -> "星期四";
case5 -> "星期五";
case6, 7 -> "周末";
default -> "无效日期";
};

如果需要更复杂的逻辑,可以使用代码块和yield关键字:

String result = switch (status) {
case"PENDING" -> {
        log.info("处理待定状态");
        yield "处理中";
    }
case"APPROVED" -> {
        log.info("处理已批准状态");
        yield "已完成";
    }
default -> "未知状态";
};

箭头语法与多分支处理

新的 switch 语法支持使用箭头->来简化代码,并且可以在一个 case 中处理多个值:

Seasonseason=switch (month) {
case3, 4, 5 -> Season.SPRING;
case6, 7, 8 -> Season.SUMMER;
case9, 10, 11 -> Season.AUTUMN;
case12, 1, 2 -> Season.WINTER;
default -> thrownewIllegalArgumentException("无效月份");
};

代码可读性的平衡

虽然这些新特性可以让代码更简洁,但也要注意不要过度使用,导致代码难以理解。保持适度,让代码既简洁又清晰。

七、其他实用特性大集合
私有接口方法

从 JDK 9 开始,接口可以包含私有方法,这在实现默认方法时非常有用:

public interface Logger {
    default void logInfo(String message) {
        log(message, "INFO");
    }

    default void logError(String message) {
        log(message, "ERROR");
    }

    // 私有辅助方法
    private void log(String message, String level) {
        System.out.println("[" + level + "] " + message);
    }
}

改进的 Stream API

JDK 17 中的 Stream API 增加了一些实用方法:

// 将流转换为List(不需要再调用collect(Collectors.toList()))
List

 names = people.stream()                           .map(Person::name)                           .filter(name -> name.startsWith("张"))                           .toList(); // 新的mapMulti方法,可以为每个元素生成多个结果 List

 words = sentences.stream()                              .mapMulti((sentence, consumer) -> {                                  for (String word : sentence.split(" ")) {                                      consumer.accept(word);                                  }                              })                              .toList(); 


增强的 NullPointerException

JDK 17 中的 NullPointerException 会提供更详细的错误信息,指出哪个变量是 null:

// 旧版本的错误信息
Exception in thread "main" java.lang.NullPointerException

// JDK 17 的错误信息
Exception in thread "main" java.lang.NullPointerException: 
  Cannot invoke "Person.getName()" because "person" is null

这大大提高了调试效率,不再需要猜测哪个对象是 null。

新的垃圾收集器

JDK 17 提供了多种垃圾收集器选项,包括 ZGC(Z Garbage Collector),它能够处理 TB 级别的堆内存,同时保持低于 10ms 的暂停时间:

// 启用ZGC的JVM参数
-XX:+UseZGC

外部内存访问 API

JDK 17 引入了外部内存访问 API,允许 Java 程序安全地访问堆外内存:

// 分配堆外内存
try (MemorySegment segment = MemorySegment.allocateNative(100)) {
    // 写入数据
    MemoryAccess.setInt(segment, 0, 42);

    // 读取数据
    int value = MemoryAccess.getInt(segment, 0);
    System.out.println(value); // 输出: 42
}

这对于需要与本地代码交互或处理大量数据的应用程序特别有用。

来源:https://juejin.cn/post/7506039220218707995

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!

文章有帮助的话,点在看,转发吧!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
美伊停火到期前48小时“极限博弈”:伊朗手握海峡“核按钮”,特朗普威胁炸桥炸电厂

美伊停火到期前48小时“极限博弈”:伊朗手握海峡“核按钮”,特朗普威胁炸桥炸电厂

红星新闻
2026-04-20 18:03:39
日本一观光直升机坠入火山口,2名中国台湾游客与1名日本机长失踪已3月,日媒称生还可能性极低,拟动用无人机重机具进入火口作业

日本一观光直升机坠入火山口,2名中国台湾游客与1名日本机长失踪已3月,日媒称生还可能性极低,拟动用无人机重机具进入火口作业

大风新闻
2026-04-20 15:11:31
北约31国集体访日,高市早苗连夜修宪,最危险的信号已经到来!

北约31国集体访日,高市早苗连夜修宪,最危险的信号已经到来!

易玄
2026-04-20 02:45:44
英国超新星穆迪抢丁俊晖风头,戴维斯:他或破最年轻世界冠军纪录

英国超新星穆迪抢丁俊晖风头,戴维斯:他或破最年轻世界冠军纪录

杨华评论
2026-04-20 21:00:34
全场哗然!29岁女子在相亲舞台称“娶我一定让你爽”,王婆也懵了

全场哗然!29岁女子在相亲舞台称“娶我一定让你爽”,王婆也懵了

火山詩话
2026-04-19 06:42:57
突发!340亿开源巨头彻底撤离中国,419名顶级工程师被疯抢,18年深耕终落幕…

突发!340亿开源巨头彻底撤离中国,419名顶级工程师被疯抢,18年深耕终落幕…

新浪财经
2026-04-20 04:31:06
日本将地震震级调整至7.5级

日本将地震震级调整至7.5级

界面新闻
2026-04-20 16:30:33
国际奥委会明确表态,对2036年奥运会的申办情况很是失望

国际奥委会明确表态,对2036年奥运会的申办情况很是失望

安安说
2026-04-20 11:09:20
日本地震震级修正为7.7级

日本地震震级修正为7.7级

界面新闻
2026-04-20 18:59:43
为什么全国人民都在拒接电话?

为什么全国人民都在拒接电话?

黯泉
2026-04-18 17:00:56
太扎心了!上海男子年薪百万失业引不满,新婚3个月女子就想离婚

太扎心了!上海男子年薪百万失业引不满,新婚3个月女子就想离婚

火山詩话
2026-04-20 06:12:18
人心散了!34分惨败引发内讧,赵继伟发社媒表达不满,怒喷队友

人心散了!34分惨败引发内讧,赵继伟发社媒表达不满,怒喷队友

南海浪花
2026-04-20 23:37:05
普京访华行程敲定,特朗普已下命令,中国向全球通告,无惧美国

普京访华行程敲定,特朗普已下命令,中国向全球通告,无惧美国

桑启红原
2026-04-20 20:19:05
海外版“砍一刀”被美国消费者疯狂吐槽:这质量就是中国制造?

海外版“砍一刀”被美国消费者疯狂吐槽:这质量就是中国制造?

可达鸭面面观
2026-04-20 16:18:29
5月1日起物业行业彻底大变天!新规落地,业主终于不用再忍气吞声

5月1日起物业行业彻底大变天!新规落地,业主终于不用再忍气吞声

另子维爱读史
2026-04-19 19:37:43
贝索斯火箭回收成功,卫星却丢了

贝索斯火箭回收成功,卫星却丢了

野生运营
2026-04-20 02:38:54
小学生拒绝借车遭殴打搜家,一名施暴者及家长上门道歉,教育局称校园欺凌专干介入,警方:“入室抢劫案”仍在调查

小学生拒绝借车遭殴打搜家,一名施暴者及家长上门道歉,教育局称校园欺凌专干介入,警方:“入室抢劫案”仍在调查

极目新闻
2026-04-20 16:20:59
揭开“白左圣母”的真面目

揭开“白左圣母”的真面目

名人苟或
2026-04-20 07:08:34
那番绝境,大帝终究还要面对

那番绝境,大帝终究还要面对

虚声
2026-04-20 08:08:29
原雷神山院长落马,其“权色交易”的背后,坑害了多少女医护家庭

原雷神山院长落马,其“权色交易”的背后,坑害了多少女医护家庭

长安一孤客
2026-04-20 18:58:28
2026-04-21 04:56:49
Java精选
Java精选
一场永远也演不完的戏
1784文章数 3859关注度
往期回顾 全部

科技要闻

HUAWEI Pura X Max发布 售价10999元起

头条要闻

19岁女孩挪用自家1700万当"榜一大姐" 亲爹带女儿自首

头条要闻

19岁女孩挪用自家1700万当"榜一大姐" 亲爹带女儿自首

体育要闻

阿森纳已拼尽全力,但你早干嘛去了...

娱乐要闻

《八千里路云和月》田家泰暗杀

财经要闻

利润暴跌7成,字节到底在做什么

汽车要闻

把天门山搬进厂?开仰望U8冲上45度坡的那刻 我腿软了

态度原创

家居
艺术
亲子
时尚
军事航空

家居要闻

自然慢调 慢享时光

艺术要闻

沙特官宣:全球最大单体建筑,延期十年!网友:又是画饼?

亲子要闻

【孤独症科普】啥是孤独症,哪些孩子易发生,如何应对?

春天衣服不用准备太多!这几大单品提前备好,百搭实用又不过时

军事要闻

特朗普:美舰向伊朗货船开火炸出个洞

无障碍浏览 进入关怀版