news 2026/2/10 22:42:42

新来的技术组长升级Java8到Java21,真是爽的飞起!!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
新来的技术组长升级Java8到Java21,真是爽的飞起!!

1.背景

众所周知,Oracle 在 2014 年发布了 JDK8,便成为了 Java 开发最主流的版本,时隔今日已经过去 10 个年头,已经发布到 JDK24 版本,在众多版本中,JDK8、JDK11、JDK17 、JDK21和 最新发布的JDK25这五个是 Oracle 官方长期支持维护的版本。

本文将结合我个人日常使用新特性的心路历程,详细对比 Java 8 与 Java 21 的实现方式来让你感受升级带来的新特性让开发可以变得如此高效优雅和高效实用,并标注每个特性的引入预览版本、转正版本以及实用性推荐指数,当然了这可能只是我个人习惯主观认为哈,如果你觉得不过客观,那只能求同存异了。

内容概览:

2.预览新特性

预览新特性其实就是一个预览功能,该功能的设计,规格和实现是完整的,但不是永久性的,这意味着该功能可能以其他形式存在或在将来的 JDK 版本中根本不存在。 要编译和运行包含预览功能的代码,必须指定其他命令行选项

作为预览特性加入,需要在javac编译和java运行时增加参数--enable-preview

简单来说预览新特性就是先让大家试用,在使用中验证该特性的实用性,最终决定是否正式发布,这是 JDK 作为标准平台在增加新特性的科学严谨态度。不再想当然地引入功能结果却没人用,比如说 Java8 里面发送 http 请求的封装就无人问津~~~

话不多说,下面就开始介绍实用新特性。

3.instanceof 模式匹配

instanceof的作用是 object 对象类型判断,一般在一些抽象封装底层组件就常用到,比如在统一响应结果封装和全局异常处理就有用到,示例如下:

Java8

if (e instanceof MethodArgumentNotValidException) { // 参数检验异常 MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) e; BindingResult result = methodArgumentNotValidException.getBindingResult(); ..... }

Java21

if (e instanceof MethodArgumentNotValidException methodArgumentNotValidException) { // 参数检验异常 BindingResult result = methodArgumentNotValidException.getBindingResult(); ...... }

这是对参数检验异常的处理,Java8 需要先判断异常 e 是不是MethodArgumentNotValidException,是的话再做类型转换才能使用,代码显得冗余麻烦,我个人就不太喜欢在代码写强制类型转换~~~,Java21 写法就很优雅了,一步到位。

引入版本:JDK 14 (预览),JDK 16 转正

实用推荐指数:⭐️⭐️⭐️⭐️⭐️

4.Switch 表达式

平时写switch容易漏写 break 导致 bug,并且代码显得不够整洁优雅,所以 JDK 对其进行了增强,示例如下:

Java8

String dayType; switch (day) { case1: case2: case3: case4: case5: dayType = "Weekday"; break; case6: case7: dayType = "Weekend"; break; default: thrownew IllegalArgumentException("Invalid day: " + day); }

Java21

String dayType = switch (day) { case 1, 2, 3, 4, 5 -> "Weekday"; case 6, 7 -> "Weekend"; default -> throw new IllegalArgumentException("Invalid day: " + day); };

一眼便可看出增强之后代码更加紧凑简洁,同时可以直接返回值避免了漏写 break 的问题

引入版本:JDK 12(预览),JDK 14 转正

实用推荐指数:⭐️⭐️⭐️⭐️⭐️

5.模式匹配 switch

这是基于上面的 3 和 4 的一次增强,因为我们在使用instanceof判断类型转换时往往伴随着条件判断,示例如下:

Java8

String format(Object obj) { if (obj instanceof Integer) { return String.format("int %d", obj); } else if (obj instanceof Long) { return String.format("long %d", obj); } else if (obj instanceof Double) { return String.format("double %f", obj); } else if (obj instanceof String) { return String.format("String %s", obj); } return obj.toString(); }

Java21

String format(Object obj) { return switch (obj) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); case null -> "null"; default -> obj.toString(); }; }

使用switch模式匹配确实看着代码更加简洁明了,同时支持 null 值的判断处理。

引入版本:JDK 17 (预览),JDK 21 转正

实用推荐指数:⭐️⭐️⭐️⭐️

6.文本块

之前在代码里面想定义多行文本块需要借助于换行符和转义符搞定,全是这些字符看着非常让用头疼,所以 JDK 引入三重双引号来定义多行文本,示例如下:

Java8

String jsonStr ="{\n" + " \"name\":\"张三\",\n" + " \"age\":18\n" + "}\n";

Java21

String jsonStr = """ { "name":"张三", "age":38 } """;

多行字符串处理变得可读直观,自动处理缩进和换行,特别适合 SQL、JSON、HTML、脚本等场景

引入版本:JDK 13(预览),JDK 15 转正

实用推荐指数:⭐️⭐️⭐️⭐️⭐️

7.HTTP Client API

之前我们想发送 http 请求一般通过集成三方框架实现,如 Apache 的 httpClient 和 Spring 的 restTemplate 等等,因为使用 JDK 原生提供的功能真的很鸡肋,几乎没人用,示例如下:

Java8

HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestMethod("GET"); try (BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream()))) { String inputLine; while ((inputLine = in.readLine()) != null) { response.append(inputLine); } }

Java21

HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .timeout(Duration.ofSeconds(10)) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

更简洁的流式 API,使用起来非常丝滑,支持同步/异步,内置超时和重试机制,使用上和三方框架没啥区别

引入版本:JDK11 正式

实用推荐指数:⭐️⭐️⭐️⭐️

8.局部变量类型推断 var

这里先讲一个插叙,好几年前我看到一个非 Java 后端的同事在刷 leetcode 算法题,我当时就问他这是用啥语言谢,咋这么像 Java 啊?他来了句:这就是 Java 啊,我大吃一惊,啊,我没见 var 声明变量啊,他说这是 JDK11,支持的新特性,这就尴尬了 😓,言归正传直接看示例:

Java8

Map<String, List<Employee>> employeeMap = new HashMap<String, List<Employee>>(); Iterator<Map.Entry<String, List<Employee>>> iterator = employeeMap.entrySet().iterator();

Java21

var employeeMap = new HashMap<String, List<Employee>>(); var iterator = employeeMap.entrySet().iterator();

对比来看,var定义局部变量,可以减少样板代码,提高可读性,特别是像上面泛型嵌套场景:

TypeReference<CanalMessageDTO<Map<String, String>>> typeReference = new TypeReference<CanalMessageDTO<Map<String, String>>>() {

改为:

var typeReference = new TypeReference<CanalMessageDTO<Map<String, String>>>();

是不是可读性更高?因为很多变量的类型都是能够直接看出的。new 表达式、字面量、工厂方法、初始化表达式最终调用的方法名以及变量名本身都是包含着类型信息的,更多的类型信息不仅仅无助于阅读,更增加了语法噪声,给阅读带来了障碍。不过我个人觉得平时这种变量定义不多,所以我个人使用的不多。

实用推荐指数:⭐️⭐️⭐️

9.虚拟线程 (Virtual Threads)

作为官方长期维护两个版本 JDK 17 和 JDK 21,我个人认为 17 到 21 之间并没有带太多实用的新东西,但是为啥 21 能成长期维护版本,主要原因就是在 JDK 19 引入的重磅特性:虚拟线程,先来看看代码:

Java8

ExecutorService executor = Executors.newFixedThreadPool(200); // 受限于OS线程 Future<String> future = executor.submit(() -> { // 阻塞操作会占用OS线程 return httpClient.get(url); });

Java21

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { Future<String> future = executor.submit(() -> { // 阻塞不会占用OS线程 return httpClient.get(url); }); }

虚拟线程(Virtual Thread)是 JDK 而不是 OS 实现的轻量级线程(Lightweight Process,LWP),许多虚拟线程共享同一个操作系统线程,虚拟线程的数量可以远大于操作系统线程的数量。虚拟线程极大提高了处理性能和吞吐量,可以说一个重大的技术突破了。

引入版本:JDK 19(预览),JDK 21 转正

实用推荐指数:⭐️⭐️⭐️⭐️⭐️

10.Record 类

record关键字可以简化数据类(一个 Java 类一旦实例化就不能再修改)的定义方式,使用record代替class定义的类,只需要声明属性,就可以在获得属性的访问方法,以及toString()hashCode(),equals()方法。

类似于使用class定义类,同时使用了 lombok 插件,并打上了@Getter,@ToString,@EqualsAndHashCode注解

Java8

public class Employee { private final String name; private final String department; private final int salary; // 构造方法、getter、equals、hashCode、toString等 // 通常需要50+行样板代码 }

Java21

public record Employee(String name, String department, int salary) {}

引入版本:JDK 14(预览),JDK 16 转正

个人感觉它发布的有点晚了,要是没有 lombok 插件,肯定用起来很香。

实用推荐指数:⭐️⭐️⭐️

11.快速创建不可变集合

直接看代码:

Java8

List<String> list = Collections.unmodifiableList(Arrays.asList("a", "b"));

创建不可变 map 更麻烦~~~

Java21

List<String> list = List.of("a", "b", "c"); Set<String> set = Set.of("a", "b", "c"); Map<String, Integer> map = Map.of("a", 1, "b", 2);

这功能在 Guava 中早就有了,有点模仿 Guava 的味道,但是用 Guava 毕竟还要引入依赖,原生 JDK 提供也还是不错的,只是看大家习惯了。

引入版本:JDK 9 正式

实用推荐指数:⭐️⭐️⭐️

12.Try-With-Resources 改进

直接看代码:

Java8

try (FileInputStream fileInputStream = new FileInputStream(""); FileOutputStream fileOutputStream = new FileOutputStream("")) { } catch (IOException e) { e.printStackTrace(); }

Java21

FileInputStream fis = new FileInputStream(""); FileOutputStream fos = new FileOutputStream(""); //多资源用分号隔开 try (fis; fos) { } catch (IOException e) { e.printStackTrace(); }

代码看上去更加格式整洁

引入版本:JDK 9 正式

实用推荐指数:⭐️⭐️⭐️⭐️

13.Sequenced Collections

Sequenced Collections(序列化集合,也叫有序集合),这是一种具有确定出现顺序(encounter order)的集合(无论我们遍历这样的集合多少次,元素的出现顺序始终是固定的)。序列化集合提供了处理集合的第一个和最后一个元素以及反向视图(与原始集合相反的顺序)的简单方法。

Java8

List<Integer> list = new ArrayList<>(); if (!list.isEmpty()) { Integer first = list.get(0); Integer last = list.get(list.size() - 1); }

Java21

List<Integer> list = new ArrayList<>(); if (!list.isEmpty()) { Integer first = list.getFirst(); Integer last = list.getLast(); }

引入版本:JDK 21 正式

实用推荐指数:⭐️⭐️⭐️⭐️

14.其他新特性

这里统一的对其他特性作出简介,不再做示例,但这并不意味着这些特性就不重要了,而是碍于篇幅问题。

  • 接口私有方法

  • String 类、stream 流、optional、Files 类等增强

  • NullPointerException 异常精确提示

  • Sealed Classes 密封类

  • 使用方法句柄重新实现反射核心,提升反射性能、速度更快

  • Scoped Values (预览): 替代ThreadLocal的更优方案,尤其是在使用大量虚拟线程时

从 JDK8 到 JDK24 每一个版本的新特性详细介绍,可以在 JavaGuide 官方网站( javaguide.cn)上找到。

下图是从 JDK 8 到 JDK 24 每个版本的更新带来的新特性数量和更新时间:

15.总结

JDK 每个版本均围绕开发效率、性能、可维护性进行改进、提供新特性,但还有一个重要主题伴随着 JDK 版本的升级,那就是垃圾回收器性能提升,从 JDK 9 开始起 G1 成为默认垃圾回收器,再到 JDK 11 引入了全新的 ZGC(Z Garbage Collector)。这个名字本身就显得很牛。官方宣称 ZGC 的垃圾回收停顿时间不超过 10ms,能支持高达 16TB 的堆空间,并且停顿时间不会随着堆的增大而增加。都体现了官方对垃圾回收器性能优化提升的重视,所以升级到 Java 21 不仅是技术上的进步,更是开发体验的飞跃、性能提升的保障,你还在等什么呢?

这里再谈谈个人升级的心得体会:

作为一位坚守 JDK8 的"资深钉子户",我之前的心态和网上流传的一句话:“他发任他发,我用 Java8”一样,但我深知做一个程序员,固步自封是不行,必须保持学习新事物才能充电进阶、与时俱进,随着网上资料看到一些高版本新特性的玩法,越发按耐不住想升级的想法,最终在 Spring 团队官宣 Spring Boot3.x 将基于 Java17 开发时,Spring 作为 Java 开发生态的顶级大佬,这就告诉我们必须升级了。所以我重新安装了 IDEA2025,JDK 也安装了 17 和 21 两个版本,打算再战它个 10 年。😄

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/6 17:46:53

621-6575RC输出模块

621-6575RC 输出模块简介&#xff1a;621-6575RC 属于控制系统中的专用输出单元主要承担控制信号向现场设备的执行传递任务模块可根据控制策略输出对应的开关或控制信号适合对外部设备进行精确、有序的控制常配合各类执行元件实现动作控制模块在系统中起到信号放大与隔离的作用…

作者头像 李华
网站建设 2026/2/7 14:27:27

集商品展示、在线沟通、支付交易、社区互动于一体的综合性二手交易小程序系统源码

温馨提示&#xff1a;文末有资源获取方式面对庞大的二手交易市场需求&#xff0c;拥有一套功能齐全、运行稳定的独立商城系统是成功起步的关键。我们为您提供一款集商品展示、在线沟通、支付交易、社区互动于一体的综合性二手交易系统源码&#xff0c;旨在帮助您快速搭建一个专…

作者头像 李华
网站建设 2026/2/7 5:04:20

Nessus自定义策略模板编写指南

一、自定义策略的优势与应用场景 Nessus作为业界领先的漏洞扫描工具&#xff0c;其自定义策略功能允许软件测试人员针对特定需求&#xff08;如只扫描高风险漏洞或特定服务&#xff09;创建可复用的模板&#xff0c;从而显著提升扫描效率和精准度。例如&#xff0c;在测试Web应…

作者头像 李华
网站建设 2026/2/4 5:44:50

PPT内容粘贴到CKEDITOR为何动画失效?

教育行业文档导入功能开发记录 一、需求分析与技术选型 作为项目组核心开发成员&#xff0c;我负责实现后台试卷发布模块的文档导入功能&#xff0c;需支持Word/Excel/PPT/PDF四种格式的解析&#xff0c;并保留原始样式与图片。经过技术评估&#xff0c;决定采用以下技术栈&a…

作者头像 李华
网站建设 2026/2/10 10:15:11

大数据基于Python的电商用户消费行为分析

目录 大数据环境下电商用户消费行为分析的Python实现核心分析流程典型分析场景技术栈组合示例 项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 大数据环境下电商用户消费行为分析的Python实现 电商平台通…

作者头像 李华