JDK8升级到JDK17的新特性

前言

随着AI时代的浪潮席卷而来,人工智能技术在各行各业的应用愈发广泛,开发领域也迎来了新的变革。为了更好地适配AI场景的开发需求,SpringAI已正式发布,它为开发者提供了构建AI应用的强大工具和框架。而要使用SpringAI,与之配套的Springboot需要升级到3.X版本,这就对JDK的版本提出了新的要求——Springboot3.X明确要求JDK必须在17及以上版本。​

JDK8作为一款经典且被广泛应用的版本,陪伴开发者走过了多年,但JDK17带来了诸多新特性和性能优化,能够更好地支持现代应用开发,尤其是在应对AI相关的复杂计算和高并发场景时表现更为出色。因此,了解JDK8到JDK17的新特性,顺利完成版本升级,对于跟上技术发展步伐、提升开发效率至关重要。

各个特性的说明与代码展示

1、局部变量类型推断(var关键字,JDK10)

在JDK10中引入,允许声明局部变量时省略类型,由编译器自动推断变量类型

    /**
     * 局部变量关键字
     */
    public static void varTest() {
        // JDK 8及之前
        String message = "Hello, World!";
        User userInfo = new User("tom", 18);

        // 升级后
        var a1 = "hello ";
        var a2 = 1L;
        var user = new User("tom", 18);
        user.introduce();
        String name = user.name();
        log.info(name);
        User jerry = User.build("jerry", 20);
        jerry.introduce();
        log.info(jerry.toString());
    }

2、文本块(Text Blocks,JDK13预览,JDK15正式引入)

为多行字符串提供了更便捷的方式,无需再使用换行符和拼接符号,特别适合SQL语句、JSON字符串、HTML代码等多行文本的场景

    /**
     * 文本块
     */
    public static void textTest() {
        String old = "select *\n" +
                "from user\n" +
                "where name = \"tom\" ";
        String newStr = """
                select * 
                from user
                where name = "tom"
                """;
        log.info(old);
        log.info(newStr);
    }

3、密封类(Sealed Classes,JDK15预览,JDK17正式引入)

密封类可以限制哪些类能够继承它,增强了代码的封装性和安全性,避免了不必要的继承和扩展

/**
 * 封闭类是使用sealed修饰的类或接口,它通过permits子句明确列出允许继承或实现它的子类(称为受许可的子类)
 * <p>
 * 限制继承层次,防止未授权的类扩展。
 * 支持模式匹配(如 instanceof、switch)的完整性检查。
 * 子类必须使用final、sealed、non-sealed修饰符之一
 *
 * @author stone
 * @date 2025/7/7 16:45
 */
public sealed class Person permits PersonMan, PersonWoman, PersonUnknown {
}


/**
 * @author stone
 * @date 2025/7/7 16:45
 */
public final class PersonMan extends Person {
}


/**
 * @author stone
 * @date 2025/7/7 16:48
 */
public non-sealed class PersonUnknown extends Person {
}


/**
 * @author stone
 * @date 2025/7/7 16:45
 */
public final class PersonWoman extends Person{
}


配合instanceOfyu语法

    /**
     * 密封类
     */
    public static void sealedTest() {
        Person tom = new PersonMan();
        if (tom instanceof PersonMan man) {
            log.info(man.toString());
        }
    }

4、instanceof模式匹配(JDK16正式引入)

允许在判断的同时进行类型转换,不必再强制类型转换

        // 模式匹配: 可以直接使用变量,不需要显式的类型转换
        Object object = "111";
        if (object instanceof String str) {
            log.info(str);
        }

5、增强的switch表达式(JDK12预览,JDK14正式引入)​

可以使用箭头语法,增加yield关键字

    public static String switchTest(String day) {
        // jdk12: 引入->操作符、不需要break语句来防止穿透
        String typeOfDay = switch (day) {
            case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> "Weekday";
            case "SATURDAY", "SUNDAY" -> "Weekend";
            default -> "Unknown";
        };
        log.info(typeOfDay);

        // jdk13: 使用yield在Switch表达式中直接返回
        return switch (day) {
            case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> "Weekday";
            case "SATURDAY", "SUNDAY" -> "Weekend";
            default -> {
                if (day.isEmpty()) {
                    yield "day is empty";
                } else {
                    yield "Unknown";
                }
            }
        };
    }

6、记录类(Records,JDK16正式引入)

记录类是一种用于存储数据的简洁类,减少了样板代码的编写

/**
 * 适用于存储数据而没有复杂业务逻辑的情况
 * <p>
 * 自动生成构造器、equals()、hashCode() 和 toString() 方法,以及每个字段的 getter方法
 * 记录中,所有字段都必须在记录的参数列表中定义。
 * 记录是不可变的,默认是final的:字段一旦赋值,不能被修改。
 * 无法在记录内部定义额外的 private final字段,可以定义对应的static字段
 *
 * @author stone
 * @date 2025/7/4 16:15
 */
public record User(String name, Integer age) {

    public static final String className = "101班";

    public void introduce() {
        System.out.println(className + "=" + name + "=" + age);
    }

    public static User build(String name, Integer age) {
        return new User(name, age);
    }

}

7、空指针异常增强(JDK14)​

对空指针异常信息进行了优化,能够更精确地指出引发空指针异常的位置和原因

    public static void main(String[] args) throws Exception {
        var user = new User("tom", 18);
        System.out.println(user.name());
        user = null;
        System.out.println(user.name());
    }



Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.stone.tool.jdk17.User.name()" because "user" is null
	at com.stone.tool.jdk17.Jdk17Demo.main(Jdk17Demo.java:34)

8、Http客户端

引入新的Http Client Api,支持链式调用,同时内置了请求构建、响应处理、超时控制等功能。

涵盖GET/POST/PUT/DELETE等HTTP方法,支持表单提交、文件上传、WebSocket通信等场景

    /**
     * http客户端
     */
    public static void httpTest() throws IOException, InterruptedException {
        HttpClient client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2) // 指定 HTTP 版本
                .followRedirects(HttpClient.Redirect.NORMAL) // 自动处理重定向
                .connectTimeout(Duration.ofSeconds(10)) // 连接超时设置
                .build();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://www.baidu.com/"))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString("{\"key\":\"value\"}")) // 请求体
                .build();

        // 同步请求,阻塞线程
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        log.info("Status code: " + response.statusCode());
        log.info("Response body: " + response.body());

        System.out.println("===============================================");

        // 异步执行,不阻塞线程
        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body) // 处理响应体
                .thenAccept(body -> log.info("Response: " + body)) // 消费结果
                .exceptionally(ex -> {
                    log.error("Exception occured!", ex);
                    return null;
                });


        // 批量请求
//        List<HttpRequest> requests = Arrays.asList(request1, request2, request3);
//        CompletableFuture.allOf(
//                requests.stream()
//                        .map(req -> client.sendAsync(req, HttpResponse.BodyHandlers.ofString()))
//                        .toArray(CompletableFuture[]::new)
//        ).thenRun(() -> System.out.println("All requests completed"));


        // 字符串请求体
        HttpRequest.BodyPublishers.ofString("Hello, World!");
        // 文件请求体
        HttpRequest.BodyPublishers.ofFile(Path.of("data.json"));
        // 字节数组请求体
        HttpRequest.BodyPublishers.ofByteArray(new byte[]{1, 2, 3});
        // 空请求体(用于 GET 请求)
        HttpRequest.BodyPublishers.noBody();

        // 处理为字符串
        HttpResponse.BodyHandlers.ofString();
        // 保存到文件
        HttpResponse.BodyHandlers.ofFile(Path.of("response.txt"));
        // 处理为字节数组
        HttpResponse.BodyHandlers.ofByteArray();
        // 忽略响应体
        HttpResponse.BodyHandlers.discarding();
        // 流式处理大响应
        HttpResponse.BodyHandlers.ofInputStream();


        log.info("method end line...");
    }
    /**
     * http WebSocket客户端
     */
    public static void httpWebSocketTest() throws IOException, InterruptedException {
        WebSocket.Listener listener = new WebSocket.Listener() {
            @Override
            public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
                System.out.println("Received: " + data);
                return new CompletableFuture<>();
            }
        };
        WebSocket webSocket = HttpClient.newBuilder()
                .build()
                .newWebSocketBuilder()
                .buildAsync(URI.create("ws://echo.websocket.org"), listener)
                .join(); // 阻塞等待连接建立

        // 发送消息
        webSocket.sendText("Hello, WebSocket!", true);
        webSocket.abort();
    }

9、GC垃圾回收

新增垃圾回收器

  • ZGC(Z Garbage Collector,JDK11引入,JDK15正式转正):ZGC是一款低延迟垃圾收集器,设计目标是支持TB级内存、GC停顿时间控制在毫秒级以内,非常适合大内存、高并发的应用(如AI模型训练、大规模数据处理)
  • Shenandoah(JDK12引入,JDK17成为正式特性):Shenandoah是另一款注重低延迟的垃圾收集器,由Red Hat主导开发,与ZGC目标类似,减少停顿时间,更适合大型业务系统

代码地址

<think>我们正在讨论从JDK8升级JDK21的新特性对比。根据提供的引用,我们可以总结出以下几个关键方面的改进:1.**语言特性增强**:-**Lambda表达式和StreamAPI(JDK8引入)**:这是JDK8最重要的特性之一,它允许以函数式风格处理集合,简化了代码并提高了可读性。-**密封类(SealedClasses,JDK17引入)**:允许控制哪些类可以继承或实现某个类或接口,增强了封装性。-**模式匹配(PatternMatching,逐步引入)**:-`instanceof`模式匹配(JDK16引入,JDK17~20增强):简化类型检查和转换,如引用[4]中的示例,将类型检查和转换合并为一步。-`switch`模式匹配(JDK17预览,JDK21正式):允许在`switch`表达式中使用类型模式,使得代码更简洁。2.**模块化系统(JDK9引入)**:-引入了模块化系统(ProjectJigsaw),将JDK本身划分为模块,应用程序也可以创建自己的模块。这有助于减少应用体积,提高安全性和可维护性。3.**性能提升**:-G1垃圾回收器成为默认(JDK9),并在后续版本中持续优化。-引入了ZGC(JDK11引入,可扩展的低延迟垃圾收集器)和Shenandoah(JDK12引入,低停顿时间垃圾收集器)等新型垃圾收集器,显著降低停顿时间。-其他性能优化包括改进的字符串操作、压缩字符串(JDK9)等。4.**API增强**:-新的日期时间API(JDK8引入):`java.time`包提供了更强大、易用的日期时间处理功能。-集合工厂方法(JDK9):使用`List.of()`,`Set.of()`,`Map.of()`等静态方法创建不可变集合。-响应式编程(ReactiveProgramming)支持:JDK9引入了`Flow`类,支持响应式流编程。-新的HTTP客户端(JDK11引入):替代了传统的`HttpURLConnection`,支持HTTP/2和WebSocket。5.**开发体验改进**:-多版本JAR文件(JDK9):允许为不同的JDK版本提供不同的类实现。-JShell(JDK9):交互式JavaREPL工具,方便快速测试代码片段。-记录类(RecordClasses,JDK16引入):简化了数据载体的定义,自动生成`equals()`,`hashCode()`,`toString()`等方法。-文本块(TextBlocks,JDK15引入):方便处理多行字符串,避免转义和连接操作。6.**现代化框架支持**:-引用[1]提到,许多现代化框架(如SpringBoot、Quarkus)已经全面支持JDK21的新特性。7.**其他重要特性**:-**虚拟线程(VirtualThreads,JDK19预览,JDK21正式)**:这是JDK21的一个重要特性,它使得编写高吞吐量的并发应用变得更加简单,可以显著提高应用程序的并发能力而无需改变编程模型。-**结构化并发(StructuredConcurrency,JDK19预览,JDK21正式)**:简化多线程编程,将多个任务视为一个工作单元,从而简化错误处理和取消操作。总结来说,从JDK8升级JDK21可以带来:-更简洁、易读的代码(Lambda、Stream、记录类、模式匹配等)-更好的性能(新垃圾收集器、其他运行时优化)-更强的安全性和可维护性(模块化系统)-更丰富的API(新的日期时间、HTTP客户端等)-更现代化的并发编程模型(虚拟线程、结构化并发)当然,升级时也需要注意兼容性问题,特别是模块化系统可能会对现有项目产生影响。建议逐步升级,并利用工具(如`jdeprscan`检查废弃API)来评估升级风险。下面我们列出一些关键版本引入的主要特性(从JDK8JDK21):-**JDK8(2014)**:-Lambda表达式-方法引用-默认方法(接口中)-StreamAPI-新的日期时间API(java.time)-Optional类-**JDK9(2017)**:-模块系统(ProjectJigsaw)-JShell-集合工厂方法(`List.of()`,`Set.of()`,`Map.of()`)-改进的StreamAPI(新增方法如`takeWhile`,`dropWhile`)-响应式流(FlowAPI)-多版本JAR文件-**JDK10(2018)**:-局部变量类型推断(`var`关键字)-**JDK11(2018)**:-HTTP客户端(标准)-字符串API增强(`isBlank`,`lines`,`strip`等)-启动单文件源代码程序(直接运行.java文件)-ZGC(实验性)-**JDK12~16**(逐步引入):-Switch表达式(JDK12预览,14正式)-文本块(JDK13预览,15正式)-记录类(JDK14预览,16正式)-模式匹配的`instanceof`(JDK14预览,16正式)-密封类(JDK15预览,16正式)-**JDK17(2021)**:-密封类正式-模式匹配的`switch`(预览)-移除实验性AOT和JIT编译器-**JDK18~21**:-模式匹配的`switch`(持续改进,JDK21正式)-虚拟线程(JDK19预览,JDK21正式)-结构化并发(JDK19预览,JDK21正式)-记录模式(JDK19预览,JDK21正式)如果你正在使用JDK8升级JDK21将是一次巨大的飞跃。建议逐步升级,例如先升级JDK11,然后再升级JDK17,最后到JDK21,这样可以分阶段解决兼容性问题。§§相关问题§§1.升级JDK时如何检查代码的兼容性?2.虚拟线程与传统线程有什么区别?它们如何提高并发性能?3.在JDK21中,模块化系统(JPMS)对现有项目有哪些主要影响?如何迁移?4.JDK21中垃圾收集器(如ZGC)有哪些改进?如何选择合适的垃圾收集器?5.记录类(Record)在实际开发中有哪些典型应用场景?</think>### JDK 8JDK 21 新特性对比分析 #### 一、核心语言特性升级 1. **函数式编程(JDK 8)** - **Lambda表达式**:简化匿名内部类 ```java List<String> list = Arrays.asList("a", "b"); list.forEach(s -> System.out.println(s)); ``` - **Stream API**:函数式集合操作 ```java list.stream().filter(s -> s.startsWith("a")).count(); ``` 2. **模式匹配(JDK 16~21)** - **类型匹配简化**(引用[4]): ```java // JDK 17+ 模式匹配 if (obj instanceof String str) { System.out.println(str.toUpperCase()); } ``` 3. **密封类(JDK 17)**(引用[3]): ```java sealed abstract class Animal permits Dog, Cat {} final class Dog extends Animal {} // 仅允许指定子类 ``` 4. **记录类(JDK 16)**: ```java record Point(int x, int y) {} // 自动生成equals/hashCode ``` #### 二、性能与内存优化 1. **垃圾收集器升级** - **ZGC**(JDK 15正式):亚毫秒级暂停时间 - **Shenandoah**(JDK 12):低停顿垃圾收集器 - 对比JDK 8的Parallel GC,延迟降低90%+[^1] 2. **虚拟线程(JDK 21)**: ```java Thread.startVirtualThread(() -> { System.out.println("轻量级线程"); }); ``` - 支持百万级并发线程,资源消耗接近异步编程[^1] #### 三、API与开发体验 1. **新HTTP客户端(JDK 11)**: ```java HttpClient.newHttpClient().sendAsync(request, BodyHandlers.ofString()); ``` - 支持HTTP/2和WebSocket 2. **文本块(JDK 15)**: ```java String json = """ { "name": "Java", "version": 21 }"""; ``` 3. **模块化系统(JDK 9)**: - `module-info.java` 显式声明依赖,增强安全性 #### 四、升级收益与挑战 | 维度 | JDK 8 | JDK 21改进 | |-------------|---------------------------|-------------------------------------| | **性能** | 基础性能 | 最高提升4倍吞吐量(Vector API等)[^1] | | **内存** | 堆内存管理效率较低 | ZGC/弹性元空间减少30%内存占用[^2] | | **安全** | 较弱模块隔离 | 强模块化+FFI API隔离本地代码[^3] | | **维护** | 2026年停止扩展支持 | 长期支持版本(LTS)至2031年 | > **升级建议**: > - ✅ **推荐升级**:新项目直接采用JDK 21,利用虚拟线程/模式匹配等特性 > - ⚠️ **注意事项**: > - 检查依赖兼容性(尤其反射操作模块) > - 使用`jdeps --jdk-version 21`分析迁移风险 > - 框架支持:Spring Boot 3.2+、Quarkus等已全面适配[^1] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值