2026/4/18 9:25:18
网站建设
项目流程
当今做那些网站致富,南昌市房产网,一个网页的制作,成都网站建设服务1.背景
众所周知#xff0c;Oracle 在 2014 年发布了 JDK8#xff0c;便成为了 Java 开发最主流的版本#xff0c;时隔今日已经过去 10 个年头#xff0c;已经发布到 JDK24 版本#xff0c;在众多版本中#xff0c; JDK8、JDK11、JDK17 、JDK21 和 最新发布的 JDK25 这五…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 对象类型判断一般在一些抽象封装底层组件就常用到比如在统一响应结果封装和全局异常处理就有用到示例如下Java8if (e instanceof MethodArgumentNotValidException) { // 参数检验异常 MethodArgumentNotValidException methodArgumentNotValidException (MethodArgumentNotValidException) e; BindingResult result methodArgumentNotValidException.getBindingResult(); ..... }Java21if (e instanceof MethodArgumentNotValidException methodArgumentNotValidException) { // 参数检验异常 BindingResult result methodArgumentNotValidException.getBindingResult(); ...... }这是对参数检验异常的处理Java8 需要先判断异常 e 是不是MethodArgumentNotValidException是的话再做类型转换才能使用代码显得冗余麻烦我个人就不太喜欢在代码写强制类型转换~~~Java21 写法就很优雅了一步到位。引入版本JDK 14 (预览)JDK 16 转正实用推荐指数⭐️⭐️⭐️⭐️⭐️4.Switch 表达式平时写switch容易漏写 break 导致 bug并且代码显得不够整洁优雅所以 JDK 对其进行了增强示例如下Java8String dayType; switch (day) { case1: case2: case3: case4: case5: dayType Weekday; break; case6: case7: dayType Weekend; break; default: thrownew IllegalArgumentException(Invalid day: day); }Java21String 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判断类型转换时往往伴随着条件判断示例如下Java8String 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(); }Java21String 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 引入三重双引号来定义多行文本示例如下Java8String jsonStr {\n \name\:\张三\,\n \age\:18\n }\n;Java21String jsonStr { name:张三, age:38 } ;多行字符串处理变得可读直观自动处理缩进和换行特别适合 SQL、JSON、HTML、脚本等场景引入版本JDK 13(预览)JDK 15 转正实用推荐指数⭐️⭐️⭐️⭐️⭐️7.HTTP Client API之前我们想发送 http 请求一般通过集成三方框架实现如 Apache 的 httpClient 和 Spring 的 restTemplate 等等因为使用 JDK 原生提供的功能真的很鸡肋几乎没人用示例如下Java8HttpURLConnection 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); } }Java21HttpClient client HttpClient.newHttpClient(); HttpRequest request HttpRequest.newBuilder() .uri(URI.create(url)) .timeout(Duration.ofSeconds(10)) .build(); HttpResponseString response client.send(request, HttpResponse.BodyHandlers.ofString());更简洁的流式 API使用起来非常丝滑支持同步/异步内置超时和重试机制使用上和三方框架没啥区别引入版本JDK11 正式实用推荐指数⭐️⭐️⭐️⭐️8.局部变量类型推断 var这里先讲一个插叙好几年前我看到一个非 Java 后端的同事在刷 leetcode 算法题我当时就问他这是用啥语言谢咋这么像 Java 啊他来了句这就是 Java 啊我大吃一惊啊我没见 var 声明变量啊他说这是 JDK11支持的新特性这就尴尬了 言归正传直接看示例Java8MapString, ListEmployee employeeMap new HashMapString, ListEmployee(); IteratorMap.EntryString, ListEmployee iterator employeeMap.entrySet().iterator();Java21var employeeMap new HashMapString, ListEmployee(); var iterator employeeMap.entrySet().iterator();对比来看var定义局部变量可以减少样板代码提高可读性特别是像上面泛型嵌套场景:TypeReferenceCanalMessageDTOMapString, String typeReference new TypeReferenceCanalMessageDTOMapString, String() {改为var typeReference new TypeReferenceCanalMessageDTOMapString, String();是不是可读性更高因为很多变量的类型都是能够直接看出的。new 表达式、字面量、工厂方法、初始化表达式最终调用的方法名以及变量名本身都是包含着类型信息的更多的类型信息不仅仅无助于阅读更增加了语法噪声给阅读带来了障碍。不过我个人觉得平时这种变量定义不多所以我个人使用的不多。实用推荐指数⭐️⭐️⭐️9.虚拟线程 (Virtual Threads)作为官方长期维护两个版本 JDK 17 和 JDK 21我个人认为 17 到 21 之间并没有带太多实用的新东西但是为啥 21 能成长期维护版本主要原因就是在 JDK 19 引入的重磅特性虚拟线程先来看看代码Java8ExecutorService executor Executors.newFixedThreadPool(200); // 受限于OS线程 FutureString future executor.submit(() - { // 阻塞操作会占用OS线程 return httpClient.get(url); });Java21try (var executor Executors.newVirtualThreadPerTaskExecutor()) { FutureString future executor.submit(() - { // 阻塞不会占用OS线程 return httpClient.get(url); }); }虚拟线程Virtual Thread是 JDK 而不是 OS 实现的轻量级线程(Lightweight ProcessLWP许多虚拟线程共享同一个操作系统线程虚拟线程的数量可以远大于操作系统线程的数量。虚拟线程极大提高了处理性能和吞吐量可以说一个重大的技术突破了。引入版本JDK 19(预览)JDK 21 转正实用推荐指数⭐️⭐️⭐️⭐️⭐️10.Record 类record关键字可以简化数据类一个 Java 类一旦实例化就不能再修改的定义方式使用record代替class定义的类只需要声明属性就可以在获得属性的访问方法以及toString()hashCode(),equals()方法。类似于使用class定义类同时使用了 lombok 插件并打上了Getter,ToString,EqualsAndHashCode注解Java8public class Employee { private final String name; private final String department; private final int salary; // 构造方法、getter、equals、hashCode、toString等 // 通常需要50行样板代码 }Java21public record Employee(String name, String department, int salary) {}引入版本JDK 14(预览)JDK 16 转正个人感觉它发布的有点晚了要是没有 lombok 插件肯定用起来很香。实用推荐指数⭐️⭐️⭐️11.快速创建不可变集合直接看代码Java8ListString list Collections.unmodifiableList(Arrays.asList(a, b));创建不可变 map 更麻烦~~~Java21ListString list List.of(a, b, c); SetString set Set.of(a, b, c); MapString, Integer map Map.of(a, 1, b, 2);这功能在 Guava 中早就有了有点模仿 Guava 的味道但是用 Guava 毕竟还要引入依赖原生 JDK 提供也还是不错的只是看大家习惯了。引入版本JDK 9 正式实用推荐指数⭐️⭐️⭐️12.Try-With-Resources 改进直接看代码Java8try (FileInputStream fileInputStream new FileInputStream(); FileOutputStream fileOutputStream new FileOutputStream()) { } catch (IOException e) { e.printStackTrace(); }Java21FileInputStream fis new FileInputStream(); FileOutputStream fos new FileOutputStream(); //多资源用分号隔开 try (fis; fos) { } catch (IOException e) { e.printStackTrace(); }代码看上去更加格式整洁引入版本JDK 9 正式实用推荐指数⭐️⭐️⭐️⭐️13.Sequenced CollectionsSequenced Collections序列化集合也叫有序集合这是一种具有确定出现顺序encounter order的集合无论我们遍历这样的集合多少次元素的出现顺序始终是固定的。序列化集合提供了处理集合的第一个和最后一个元素以及反向视图与原始集合相反的顺序的简单方法。Java8ListInteger list new ArrayList(); if (!list.isEmpty()) { Integer first list.get(0); Integer last list.get(list.size() - 1); }Java21ListInteger 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 引入了全新的 ZGCZ Garbage Collector。这个名字本身就显得很牛。官方宣称 ZGC 的垃圾回收停顿时间不超过 10ms能支持高达 16TB 的堆空间并且停顿时间不会随着堆的增大而增加。都体现了官方对垃圾回收器性能优化提升的重视所以升级到 Java 21 不仅是技术上的进步更是开发体验的飞跃、性能提升的保障你还在等什么呢这里再谈谈个人升级的心得体会作为一位坚守 JDK8 的资深钉子户我之前的心态和网上流传的一句话“他发任他发我用 Java8”一样但我深知做一个程序员固步自封是不行必须保持学习新事物才能充电进阶、与时俱进随着网上资料看到一些高版本新特性的玩法越发按耐不住想升级的想法最终在 Spring 团队官宣 Spring Boot3.x 将基于 Java17 开发时Spring 作为 Java 开发生态的顶级大佬这就告诉我们必须升级了。所以我重新安装了 IDEA2025JDK 也安装了 17 和 21 两个版本打算再战它个 10 年。