Brandon's Blog

Brandon's Blog

现代 Java 新特新

125
2023-12-03
现代 Java 新特新

前言

Java 8 自 2014 年 3 月18 日发布至今(2024), 这么多年过去了依然是国内使用最广泛的 JDK 版本, 正所谓 "他发任他发, 我用 Java 8", 突出一个字啊! 先来康一康 Java SE RoadMap:

Java 8 之后的10年里 Oracle 先后发布了13个版本, 其中3个 LTS 版本, 从里面的 Release 的功能可以看出来 Java 一直紧跟时代, 变化非常大, 总的来说就是迈向更轻(体积), 更快(性能), 更小(内存占用). 作为一个有灵魂码农, 也不能落后, 可以不用, 但不能不了解.

关于 Java 8 的介绍可以看我的老文章: Java8 Noob Tutorial

Java 9 - 11

Java 9

主要语言变化

新增

  • 模块化系统(Module System): JSR 376

    • Project Jigsaw 的一部分

    • 按需加载, 解决臃肿

    • module-info.java

      • 通过 exports, requires 关键字声明作用域(感觉像 nodejs?)

  • 新版本定义机制: $MAJOR.$MINOR.$SECURITY.$PATCH

更新

  • try-with-resources 语法允许变量使用 final 修饰, 语法升级

  • diamond 语法允许匿名类(如果类型推断的参数类型可表示的话)

  • 接口允许定义 private 方法

  • @SafeVarargs 允许声明在实例 private 方法上

主要 API 变化

引入

  • 进程(Process): JEP 102, 全新 API ProcessHandle 提供更好的管控操作系统

  • 内存(Memory): JEP 193, VarHandle 作为正式 API 替代 Unsafe, 对变量执行原子和内存屏障操作

  • 日志(Logging): JEP 264, 全新日志 API 和服务

    • 现在基本都用 Slf4j 了吧...

  • XML: JEP 268, 添加标准的 XML Catalog API

  • 栈(Stack): JEP 259, 全新栈跟踪工具, StackWalker 替代老的 StackTraceElement 体系

更新

  • 字符串(String): JEP 254, String 底层存储char[] 替换为 byte[]

    • 内存优化, 时间换空间

  • 集合(Collections): JEP 269, 集合接口提供便利的工厂方法, 如, Set.of(...)

  • 并发(Concurrency): JEP 266, CompletableFuture 以及其他并发组件提升

    • Reactive Streams: java.util.concurrent.Flow

  • 编译器(Compiler): JEP 274, 提升 MethodHandle 通用性以及更好地编译优化

  • 注解(Annotation): JEP 277, @Deprecated 注解增加 sinceforRemoval 属性, 丰富 API 淘汰策略

  • 线程(Threading): JEP 285, 新增自选方法 Thread.onSpinWait

  • 对象序列化(Serialization): JEP 290, 新增 API ObjectInputFilter 过滤 ObjectInputStream

  • XML: JEP 255, 更新 Xerces 2.11.0 解析 XML

  • Java Management Extensions (JMX): 支持远程诊断命令

  • 脚本(Scripting):

    • JEP 236, Nashorn 解析器 API 引入

    • JEP 292, 实现 ECMAScript 6 功能

  • 国际化(Internationalization):

    • JEP 267, 支持 Unicode 8.0

    • JEP 252, JDK 8 引入的 XML 形式的 Common Locale Data Repository (CLDR) 作为默认选项

    • JEP 226, 支持 UTF-8 Properties 文件

  • Java Database Connectivity (JDBC):

    • JDBC-ODBC 桥接移除

    • JDBC 4.2 升级

主要 JVM 变化

新增

更新

  • 垃圾回收(Garbage Collection)

  • 统一 JVM 日志: JEP 158

  • 输入/输出(I/O):

    • 减少 <JDK_HOME>/jre/lib/charsets.jar 文件大小

  • 性能提升(Performance)

    • java.lang.String 字节数组性能优化

  • 工具(Tools)

    • Java Plug-in 标记为不推荐使用, 未来版本移除

    • jshell: JEP 222, 增加 Read-Eval-Print Loop

    • jcmd: JEP 228, 增加更多诊断命令

    • jlink: JEP 282, 组装和优化模块以及依赖

    • 多版本发布 JAR 文件: JEP 238

    • 移除指定版本 JRE 启动

    • 移除 HProf Agent: JEP 240

Java 10

主要语言变化

新增

主要 API 变化

更新

  • 通用: Optional 新增方法

    • orElseThrow()方法来在没有值时抛出指定的异常

  • 集合增强

    • List, Set, Map 提供了静态方法copyOf()返回入参集合的一个不可变拷贝

  • java.util.stream.Collectors 中新增了静态方法, 用于将流中的元素收集为不可变的集合

  • Collectors.toUnmodifiableList(), Collectors.toUnmodifiableSet()

  • 安全(Security):

主要 JVM 变化

新增

更新

Java 11(LTS)

主要语言变化

新增

主要 API 变化

引入

更新

主要 JVM 变化

新增

更新

Java 12 - 17

Java 12

主要语言变化

新增

主要 API 变化

  • String 新增了 indent 方法处理缩进

  • Files 新增了 mismatch 来对比两个文件

  • NumberFormat 新增了对复杂的数字进行格式化的支持: getCompactNumberInstance

主要 JVM 变化

新增

更新

Java 13

主要语言变化

新增

主要 API 变化

更新

主要 JVM 变化

更新

Java 14

主要语言变化

新增

主要 API 变化

引入

主要 JVM 变化

更新

Java 15

主要语言变化

引入

更新

主要 API 变化

引入

更新

主要 JVM 变化

更新

Java 16

主要语言变化

引入

更新

引入

主要 JVM 变化

引入

更新

Java 17(LTS)

主要语言变化

引入

更新

主要 API 变化

引入

更新

主要 JVM 变化

引入

更新

Java 18 - 21

Java 18

主要语言变化

更新

主要 API 变化

更新

主要 JVM 变化

更新

Java 19

主要语言变化

更新

主要 API 变化

更新

主要 JVM 变化

引入

Java 20

主要语言变化

引入

主要 API 变化

更新

Java 21(LTS)

主要语言变化

引入

更新

主要 API 变化

引入

更新

主要 JVM 变化

更新

是否升级

个人觉得现代 Java 的使用越来越偏底层, 越来越难, 很多黑科技的出现, 比如指令优化等, 这些都不是给没有经验的小白玩的, 而是给资深有经验的人使用的, 所以了解这些高级特性是提升个人竞争力的有效途径.

从 Java 8 到 21, 无论是性能还是内存的优化, 还是更多的底层支持, 都得到了质的飞跃(String 压缩, ZGC, GraalVm等), 但升不升级还是需要慎重考虑.

如果应用依赖比较少, 升级难度还没那么大. 如果依赖比较多, 那么就要非常慎重了, 因为由于内部 Java 内部 API 的变动(比如 @PostCostruct 被移除了, StackTrace 有了新的 API), 如果第三框架没有适配, 那就寄了. 新的项目可以尝试使用最新的版本以享受新特性带来的性能提升, 但可能很多公共模块要重新适配, 对开发人员提出更高的要求.

Ref