Java24你发任你发,我用Java8

大家好,我是晓凡。

各位 Java 开发者们!是不是还在为 Java 23 的新特性忙得焦头烂额?

别急,Java 24 已经悄咪咪地发布了!

这可是自 Java 21 以来的第三个非长期支持版本,而且这次的新特性数量直接拉满,一共有 24 个,是 Java 22 和 Java 23 的总和!

这么多新特性,学得废么?别怕,这就带大家来一探究竟,看看 Java 24 到底给我们带来了哪些"惊喜"。

一、Java 版本的江湖现状

在深入 Java 24 的新特性之前,我们先来瞅瞅 Java 各个版本的使用占比情况。

距离Java8版本已经过去了很久,但是不少小伙伴还坚守在Java8战场。凭借其稳定性和丰富的类库,在实际开发中依然占据着重要地位。

网友:"你发任你发,我用Java8!"。

根据最新的统计数据(不一定准确~),目前 Java 17 作为长期支持版本(LTS),占据了市场的半壁江山,约有 50% 的开发者在使用。

Java 11 也还有一批忠实的粉丝,占比约 30%。

而像 Java 22、Java 23 这些非长期支持版本,虽然更新频繁,但由于生命周期较短,使用占比相对较低,加起来也就 20% 左右。

不过,随着 Java 25 预计在今年 9 月份发布,作为下一个长期支持版本,相信又会掀起一波升级热潮。

二、Java 24 的新特性大揭秘

2.1 JEP 478:密钥派生函数 API(预览)

先来说说这个密钥派生函数 API。在以前,我们开发加密相关的功能时,密钥管理一直是个让人头疼的问题。要是密钥重复使用,那可就容易被黑客钻空子了。Java 24 给我们带来了解决方案,通过这个 API,我们可以使用最新的密钥派生算法,比如 HKDF 和未来可能会加入的 Argon2,来生成各种加密目的所需的密钥。这样一来,安全性就大大提升了,也为应对未来的量子计算威胁做好了准备。

代码示例:

scss 复制代码
// 创建一个 KDF 对象,使用 HKDF-SHA256 算法
KDF hkdf = KDF.getInstance("HKDF-SHA256");
// 创建 Extract 和 Expand 参数规范
AlgorithmParameterSpec params =
    HKDFParameterSpec.ofExtract()
                     .addIKM(initialKeyMaterial) // 设置初始密钥材料
                     .addSalt(salt)              // 设置盐值
                     .thenExpand(info, 32);      // 设置扩展信息和目标长度
// 派生一个 32 字节的 AES 密钥
SecretKey key = hkdf.deriveKey("AES", params);
// 可以使用相同的 KDF 对象进行其他密钥派生操作

2.2 JEP 483:提前类加载和链接

这个特性简直就是启动时间敏感应用的救星!

在传统的 JVM 中,每次启动应用都要动态加载和链接类,这对于微服务或者无服务器函数来说,简直就是噩梦,启动时间长得让人抓狂。

Java 24 通过缓存已加载和链接的类,直接减少了重复工作的开销,让大型应用的启动时间减少了 40% 以上。

而且,这个优化完全不需要我们修改应用程序、库或框架的代码,只需要添加一个 JVM 参数 -XX:+ClassDataSharing 就搞定了。

2.3 JEP 484:类文件 API

这个特性对于那些喜欢折腾 Java 类文件的开发者来说,简直就是福音。

以前我们处理类文件,还得依赖第三方库,比如 ASM。

现在 Java 24 给我们提供了一套标准化的 API,可以轻松地解析、生成和转换 Java 类文件。

这样一来,我们就可以更加方便地进行字节码操作,提升开发效率。

代码示例:

scss 复制代码
// 创建一个 ClassFile 对象,这是操作类文件的入口
ClassFile cf = ClassFile.of();
// 解析字节数组为 ClassModel
ClassModel classModel = cf.parse(bytes);
// 构建新的类文件,移除以 "debug" 开头的所有方法
byte[] newBytes = cf.build(classModel.thisClass().asSymbol(),
    classBuilder -> {
        // 遍历所有类元素
        for (ClassElement ce : classModel) {
            // 判断是否为方法且方法名以 "debug" 开头
            if (!(ce instanceof MethodModel mm
                    && mm.methodName().stringValue().startsWith("debug"))) {
                // 添加到新的类文件中
                classBuilder.with(ce);
            }
        }
    });

2.4 JEP 485:流收集器

流收集器 Stream::gather(Gatherer) 是 Java 24 中一个非常强大的新特性。它允许我们定义自定义的中间操作,从而实现更复杂、更灵活的数据转换。

与现有的 filtermapdistinct 等内置操作不同,Stream::gather 可以帮助我们完成那些难以用标准 Stream 操作完成的任务,比如滑动窗口、自定义规则的去重等。

这简直就是数据处理的瑞士军刀,大大扩展了 Stream API 的应用范围。

代码示例:

csharp 复制代码
var result = Stream.of("foo", "bar", "baz", "quux")
                   .gather(Gatherer.ofSequential(
                       HashSet::new, // 初始化状态为 HashSet,用于保存已经遇到过的字符串长度
                       (set, str, downstream) -> {
                           if (set.add(str.length())) {
                               return downstream.push(str);
                           }
                           return true; // 继续处理流
                       }
                   ))
                   .toList();
// 输出结果 ==> [foo, quux]

2.5 JEP 486:永久禁用安全管理器

这个特性可能会让一些老派的 Java 开发者感到不习惯。

Java 24 不再允许启用 Security Manager,即使通过 java -Djava.security.manager 命令也无法启用。

虽然 Security Manager 曾经是 Java 中限制代码权限的重要工具,但由于它复杂性高、使用率低且维护成本大,Java 社区决定最终移除它。

这也意味着我们在开发过程中需要寻找新的安全策略来替代它。

2.6 JEP 487:作用域值(第四次预览)

作用域值这个特性听起来有点高大上,其实它的作用非常实用。

它可以在线程内和线程间共享不可变的数据,比线程局部变量好多了,尤其是在使用大量虚拟线程时。

这样一来,我们就可以在大型程序中的组件之间安全有效地共享数据,而不用再通过方法参数传递,代码更加简洁清晰。

代码示例:

scss 复制代码
final static ScopedValue<...> V = new ScopedValue<>();
// 在某个方法中
ScopedValue.where(V, <value>)
           .run(() -> { ... V.get() ... call methods ... });
// 在被 lambda 表达式直接或间接调用的方法中
... V.get() ...

2.7 JEP 491:虚拟线程的同步而不固定平台线程

这个特性对于提升应用程序的并发能力非常有帮助。

在 Java 24 中,虚拟线程在 synchronized 方法和代码块中阻塞时,通常能够释放其占用的操作系统线程,避免了对平台线程的长时间占用。

这样一来,即使在 synchronized 块中发生阻塞,也不会固定平台线程,从而允许平台线程继续服务于其他虚拟线程,提高整体的并发性能。

这对于 I/O 密集型的应用程序来说,简直就是如虎添翼。

2.8 JEP 493:在没有 JMOD 文件的情况下链接运行时镜像

这个特性主要是为了减少 JDK 的安装体积。默认情况下,JDK 同时包含运行时镜像和 JMOD 文件。

现在,通过这个特性,jlink 工具无需使用 JDK 的 JMOD 文件就可以创建自定义运行时镜像,直接减少了约 25% 的 JDK 安装体积。

这对于那些需要在资源受限的环境中部署 Java 应用的开发者来说,简直就是福音。

2.9 JEP 495:简化的源文件和实例主方法(第四次预览)

这个特性主要针对 Java 初学者。

传统的 main 方法声明对于初学者来说,引入了太多的 Java 语法概念,不利于快速上手。

Java 24 对 main 方法的声明进行了简化,让初学者能够更快地入门。

代码示例:

没有使用该特性之前:

typescript 复制代码
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

使用该新特性之后:

csharp 复制代码
class HelloWorld {
    void main() {
        System.out.println("Hello, World!");
    }
}

进一步简化(未命名的类允许我们省略类名):

csharp 复制代码
void main() {
    System.out.println("Hello, World!");
}

2.10 JEP 497:量子抗性数字签名算法 (ML-DSA)

Java 24 还引入了支持实施抗量子的基于模块晶格的数字签名算法(ML-DSA)。

这是为了应对未来量子计算机可能带来的威胁,提前做好准备。

ML-DSA 是美国国家标准与技术研究院(NIST)在 FIPS 204 中标准化的量子抗性算法,用于数字签名和身份验证。

这个特性让我们在安全性方面又多了一层保障。

2.11 JEP 498:使用 sun.misc.Unsafe 内存访问方法时发出警告

这个特性主要是为了提醒开发者,sun.misc.Unsafe 中的内存访问方法已经在 JDK 23 中被提议弃用,并且在未来的版本中会被移除。

在 Java 24 中,当首次调用 sun.misc.Unsafe 的任何内存访问方法时,运行时会发出警告。

同时,Java 也提供了安全高效的替代方案,比如 java.lang.invoke.VarHandlejava.lang.foreign.MemorySegment

让我们可以更加安全地进行内存操作。

2.12 JEP 499:结构化并发(第四次预览)

结构化并发是 Java 19 引入的一个多线程编程方法,目的是通过结构化并发 API 来简化多线程编程。

在 Java 24 中,这个特性继续得到完善。

它将不同线程中运行的多个任务视为单个工作单元,从而简化错误处理、提高可靠性并增强可观察性。

这对于虚拟线程来说,简直就是绝配。虚拟线程是 JDK 实现的轻量级线程,许多虚拟线程共享同一个操作系统线程,从而允许非常多的虚拟线程。

代码示例:

ini 复制代码
try (var scope = new StructuredTaskScope<Object>()) {
    // 使用 fork 方法派生线程来执行子任务
    Future<Integer> future1 = scope.fork(task1);
    Future<String> future2 = scope.fork(task2);
    // 等待线程完成
    scope.join();
    // 结果的处理可能包括处理或重新抛出异常
    ... process results/exceptions ...
} // close

小结

Java 24 的发布,无疑给 Java 开发者们带来了新的挑战。

这么多的新特性,在开发过中也有了更多的选择和更强大的工具。

小伙伴:"学习进度跟不上版本更新的脚步,学不动了,要学废了~"

但从长远来看,这将有助于我们提升开发效率、优化代码质量和提升应用性能。

各位小伙伴们,你对此有什么看法呢? 欢迎评论区留言~

相关推荐
期待のcode2 分钟前
Java虚拟机的运行模式
java·开发语言·jvm
程序员老徐5 分钟前
Tomcat源码分析三(Tomcat请求源码分析)
java·tomcat
a程序小傲14 分钟前
京东Java面试被问:动态规划的状态压缩和优化技巧
java·开发语言·mysql·算法·adb·postgresql·深度优先
仙俊红15 分钟前
spring的IoC(控制反转)面试题
java·后端·spring
阿湯哥16 分钟前
AgentScope Java 集成 Spring AI Alibaba Workflow 完整指南
java·人工智能·spring
小楼v27 分钟前
说说常见的限流算法及如何使用Redisson实现多机限流
java·后端·redisson·限流算法
与遨游于天地39 分钟前
NIO的三个组件解决三个问题
java·后端·nio
czlczl200209251 小时前
Guava Cache 原理与实战
java·后端·spring
yangminlei1 小时前
Spring 事务探秘:核心机制与应用场景解析
java·spring boot
记得开心一点嘛2 小时前
Redis封装类
java·redis