Java 22 中的4个永久特性

news2024/11/15 12:41:45

在这里插入图片描述

功能处于孵化或预览阶段是什么意思?

实际上,这是向 Java 编程语言添加新功能的新过程,Java 社区使用这种过程来在 API 和工具处于早期实验阶段时从社区获得反馈(孵化功能)或已经完全指定但尚未永久的阶段(预览功能)。

预览功能是 Java 语言、Java 虚拟机或 Java SE API 的新功能,已经完全指定和实现,但尚未成为永久性的。它在 JDK 功能发布中提供,以便开发人员根据实际使用情况提供反馈,这可能导致其在未来的 Java SE 平台中成为永久功能。

孵化功能是一个 API 或工具,体量不小,正在开发中,最终将包含在 Java SE 平台或 JDK 中。该 API 或工具尚未完全验证,因此希望推迟标准化或最终确定,以便在少量功能发布中获得更多经验和反馈。

Java 22 新功能

由于 Java 22 不是 LTS 版本,了解哪些功能是非预览(或非孵化)的对想使用最新永久功能的 Java 开发人员来说非常重要。以下是该版本的功能及其状态列表:

  • (✅ 永久) G1 的区域固定
  • (✅ 永久) 外部函数和内存 API
  • (✅ 永久) 未命名变量和模式
  • (✅ 永久) 启动多文件源代码程序
  • (🔍 预览) super(…) 之前的语句
  • (🔍 预览) 类文件 API
  • (🔍 第二次预览) 字符串模板
  • (🔍 预览) 流收集器
  • (🔍 第二次预览) 结构化并发
  • (🔍 第二次预览) 隐式声明类和实例主方法
  • (🔍 第二次预览) 作用域值
  • (🧪 第七次孵化) 向量 API

如上所述,此版本只有 4 个永久性功能,可以预期它们将在下一个 LTS 版本中出现。

1- G1 的区域固定

G1(Garbage First)垃圾收集器自 JDK 9 起成为默认垃圾收集器。这个变化是为了提供更好的整体性能和更可预测的应用程序暂停时间,相较于之前的默认垃圾收集器 Parallel GC。

它首先关注垃圾最多的区域,使用并发和并行处理,并提供更可预测的暂停时间。

通过 JEP 423(G1 的区域固定),Java 22 引入了对 G1 垃圾收集器(GC)的增强。这个新功能旨在显著减少与 Java 本地接口(JNI)关键区域相关的延迟问题。

JNI(Java Native Interface)通过提供获取和释放 Java 对象的直接指针的函数,促进与 C 和 C++ 等非托管编程语言的互操作性。这些函数对内的代码在关键区域内运行,访问 Java 对象的时间被称为关键对象。传统上,G1 会在这些关键区域内禁用 GC,以防止移动对象,从而导致显著的延迟问题,如线程饥饿和应用程序阻塞。

区域固定方法通过将关键对象固定在其位置,确保 GC 能继续进行而不受阻碍,从而解决了这些问题。

总而言之,G1 的区域固定允许垃圾收集器更有效地处理固定对象,提高性能,减少 GC 暂停,并改善 Java 应用程序的内存管理效率。

2- 外部函数和内存 API

经过超过 10 年的工作,通过在 Java 22 中最终确定 JEP 454(外部函数和内存 API),我们现在有了一种比 JNI 更好的方法和 API 来与 Java 运行时之外的代码和数据进行交互。

我认为这是 Java 22 引入的最重要和最革命性的永久功能。该 API 包含两个部分:外部函数 API,它提供了一种高效调用外部函数的方法,以及内存 API,它提供了对外部内存的安全访问,例如 JVM 不管理的内存。

为了更清晰地说明,请看这段来自 bdd 博客的示例代码,展示了如何使用 FFM API 调用外部 C 函数:

void main(String[] args) {
  // 第一步:查找外部函数
  Linker linker = Linker.nativeLinker();
  SymbolLookup stdlib = linker.defaultLookup();
  MemorySegment strlenAddress = stdlib.find("strlen").orElseThrow();

  // 第二步:定义输入/输出并创建方法句柄
  FunctionDescriptor descriptor = FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS);
  MethodHandle strlen = linker.downcallHandle(strlenAddress, descriptor);

  // 第三步:管理堆外内存
  try (Arena offHeap = Arena.ofConfined()) {
    // 第四步:在堆外内存中使参数 C 兼容
    MemorySegment funcArg = offHeap.allocateFrom(args[0]);

    // 第五步:调用函数
    long len = (long) strlen.invoke(funcArg);
  }
}

如你所见,FFM 方法比 JNI 方法更易读,后者首先强迫我们使用 native 关键字定义本地方法,然后需要更多步骤来从我们的 Java 代码中调用外部函数。

外部函数和内存 API(FFM)在 Java 中相对于传统的 Java 本地接口(JNI)提供了多项显著优势。它用一种可读的纯 Java API 替代了复杂和脆弱的 JNI 方法,这使得开发人员在处理本地方法时更加轻松。该 API 处理多种内存类型中的结构化和非结构化数据,并通过防止跨线程的使用后释放错误来确保健全性。

3- 未命名变量和模式

未命名变量是 Java 中另一个期待已久的功能。如果你用过 Scala,这个功能你会很熟悉。通过最终确定这个功能,我们现在可以拥有未命名变量和未命名模式,这些可以在需要变量声明或嵌套模式但从未使用时使用。这种变量和模式用下划线字符 _ 表示。

未命名变量
以下几种声明可以引入命名变量或未命名变量:

  • 块中的局部变量声明语句
  • try-with-resources 语句的资源规范
  • 基本 for 循环的头部
  • 增强型 for 循环的头部
  • catch 块的异常参数
  • lambda 表达式的形式参数

当你声明一个未命名变量时,在初始化后你无法访问或修改它。让我们看一些代码示例:

// 带副作用的增强型 for 循环:
static int count(Iterable<Order> orders) {
    int total = 0;
    for (Order _ : orders)    // 未命名变量
        total++;
    return total;
}

// 赋值语句:
Queue<Integer> q = ... // x1, y1, z1, x2, y2, z2, ...
while (q.size() >= 3) {
   var x = q.remove();
   var y = q.remove();
   var _ = q.remove();        // 未命名变量
   ... new Point(x, y) ...
}

// catch 块:
String s = ...
try {
    int i = Integer.parseInt(s);
} catch (NumberFormatException _) {        // 未命名变量
    System.out.println("Bad number: " + s);
}

// 在 try-with-resources 中:
try (var _ = ScopedContext.acquire()) {    // 未命名变量
    // 不使用获取的资源 ...
}

// 参数无关的 lambda:
stream.collect(Collectors.toMap(String::toUpperCase,
                                   _ -> "NODATA"))    // 未命名变量

未命名模式变量
未命名模式变量可用于:

在类型模式中(包括 var 类型模式,无论该类型模式出现在顶层还是嵌套在记录模式中)

switch (ball) {
    case RedBall _   -> process(ball);          // 未命名模式变量
    case BlueBall _  -> process(ball);          // 未命名模式变量
    case GreenBall _ -> stopProcessing();       // 未命名模式变量
}

switch (box) {
    case Box(RedBall _)   -> processBox(box);   // 未命
   	case Box(BlueBall _)  -> processBox(box);   // 未命名模式变量
    case Box(GreenBall _) -> stopProcessing();  // 未命名模式变量
    case Box(var _)       -> pickAnotherBox();  // 未命名模式变量
}

多模式的 case 标签:

switch (box) {
    case Box(RedBall _), Box(BlueBall _) -> processBox(box);
    case Box(GreenBall _)                -> stopProcessing();
    case Box(var _)                      -> pickAnotherBox();
}

在未命名模式中:

if (r instanceof ColoredPoint(Point(int x, int y), _)) { ... x ... y ... }

欲了解更多描述和示例代码,请访问 官方 JEP 页面。

使用未命名变量和模式的可能问题

使用未命名变量和模式的潜在风险是,从旧版本升级的开发人员如果代码中包含下划线字符 _ 的变量,可能会遇到编译时错误或警告。此外,开发人员可能需要更新静态分析工具,以识别 _ 的新角色,并避免错误地标记其未使用。

4- 启动多文件源代码程序

这个功能是 JShell 的一个补充功能,也是 Java 11 中引入的启动单文件源代码程序功能的补充。

启动多文件源代码程序功能允许开发人员在一次 Java 启动器调用中编译和运行多个 Java 源文件。

这意味着我们现在可以在不手动编译它们的情况下执行跨多个源文件的程序。

这个增强功能简化了从源代码直接运行复杂 Java 应用程序的工作流程,提高了开发效率和便利性。它还将使从小型程序向大型程序的过渡更加渐进,使开发人员能够在项目早期阶段避免配置构建工具。

小结

网上有许多关于 Java 22 新功能的文章,如字符串模板、结构化并发或向量 API,但所有这些有趣和奇妙的功能都处于预览或孵化状态。本文回顾了那些不在预览或孵化状态的功能。对我来说,外部函数和内存 API(FFM)是最令人兴奋和革命性的功能。

你可以在 Oracle 的 官方博客文章 或 OpenJDK 网站上的 JDK 22 官方页面 阅读完整的发布报告和更多信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1943376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ConstraintLayout属性说明

ayout_constraintTop_toTopOf&#xff1a;将某一控件的顶部与另一控件的顶部对齐。 layout_constraintTop_toBottomOf&#xff1a;将某一控件的顶部与另一控件的底部对齐。 layout_constraintBottom_toTopOf&#xff1a;将某一控件的底部与另一控件的顶部对齐。 layout_cons…

3GPP R18 Multi-USIM是怎么回事?(四)

前几篇主要是MUSIM feature NAS 部分内容的总结,这篇开始看RRC部分相关的内容,由于RRC部分内容过长,也分成了2篇。这篇就着重看下musim gap以及RRC触发UE离开RRC Connected mode相关的内容,直入正题, 上面的内容在overview中有提到,对应的是如下38.300中的描述。 处于网络…

【Node.js基础02】fs、path模块

目录 一&#xff1a;fs模块-读写文件 1 加载fs模块对象 2 读制定文件内容文件 3 向文件中写入内容 二&#xff1a;path模块-路径处理 1 问题引入 2 __dirname内置变量 使用方法 一&#xff1a;fs模块-读写文件 fs模块封装了与本机文件系统交互方法和属性 1 加载fs模块…

Win11 改造

记录一些安装 win11 系统之后&#xff0c;对使用不习惯的地方&#xff0c;进行的个人改造 右键菜单 Hiyoung006/Win11Useable: 将Win11右键菜单及资源管理器恢复为Win10样式的脚本 切换到旧版右键菜单&#xff1a; reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34…

Chapter18 基于物理的渲染——Shader入门精要学习

Chapter18 基于物理的渲染 一、PBS理论和数学基础1.光是什么微表面模型 2.渲染方程3.精确光源4.双向反射分布函数 BRDF5.漫反射项&#xff08;Lambert 模型&#xff09;Lambertian BRDF为&#xff1a;Disney BRDF中漫反射项 6.高光反射项微面元理论BRDF的高光反射项①菲涅尔反射…

LabVIEW和IQ测试仪进行WiFi测试

介绍一个使用LabVIEW和LitePoint IQxel-MW IQ测试仪进行WiFi测试的系统。包括具体的硬件型号、如何实现通讯、开发中需要注意的事项以及实现的功能。 使用的硬件​ IQ测试仪型号: LitePoint IQxel-MW 电脑: 配置高效的台式机或笔记本电脑 路由器: 支持802.11ax (Wi-Fi 6) 的…

便携气象站:科技助力气象观测

在科技飞速发展的今天&#xff0c;便携气象站以其轻便、高效、全面的特点&#xff0c;正逐渐改变着气象观测的传统模式。这款小巧而强大的设备&#xff0c;不仅为气象学研究和气象灾害预警提供了有力支持&#xff0c;更为户外活动、农业生产等领域带来了诸多便利。 便携气象站是…

遗传算法模型Python代码——用Python实现遗传算法案例

一、遗传算法概述 1.1适用范围 遗传算法&#xff08;Genetic Algorithm, GA&#xff09;是一种启发式搜索算法&#xff0c;广泛应用于以下领域&#xff1a; 优化问题&#xff1a;如函数优化、路径规划、资源分配等。机器学习&#xff1a;用于特征选择、超参数优化等。经济与…

服务器系统盘存储不够,添加数据盘并挂载(阿里云)

目录 1.获取数据盘设备名称 2.为数据盘创建分区 3.为分区创建文件系统 4.配置开机自动挂载分区 阿里云数据盘挂载说明链接&#xff1a;在Linux系统中初始化小于等于2 TiB的数据盘_云服务器 ECS(ECS)-阿里云帮助中心 1.获取数据盘设备名称 sudo fdisk -lu 运行结果如下所示…

解决 elementUI 组件在 WebStorm 中显示为未知标签的问题

解决 elementUI 组件在 WebStorm 中显示为未知标签的问题 一、问题 自从转到 ts 之后&#xff0c;编辑器就一直提示用到的 elementUI 标签未知&#xff0c;一直显示一溜黄色警示&#xff0c;很烦&#xff1a; 二、解决 把它改成大写就可以了。 如下&#xff1a; 把整个项目…

【C++】学习笔记——哈希_2

文章目录 十八、哈希3. 实现哈希表哈希表的存储节点哈希函数哈希表的定义哈希表的插入哈希表的查找哈希表的删除测试函数完整代码结果 未完待续 十八、哈希 3. 实现哈希表 哈希表的实现方法有蛮多种&#xff0c;这里我们选一个比较经典的开散列法来实现哈希表。由于STL库里的…

使用PicGo操作gitee图床(及web端html不能访问图片的解决办法)

1.新建仓库 2.输入仓库名称,也就是图床名称,必须设置开源可见 也可以在创建仓库后,点击管理->基本信息->是否开源进行设置 鼠标悬浮到右上角头像->设置 点击私人令牌 点击生成新令牌,填写描述,直接点提交即可 点击提交后输入登录密码会生成一个token秘钥,如下,这个…

新版本异次元荔枝V4自动发卡系统源码

新版本异次元荔枝V4自动发卡系统源码&#xff0c;增加主站货源系统&#xff0c;支持分站自定义支付接口&#xff0c;目前插件大部分免费&#xff0c;UI页面全面更新&#xff0c;分站可支持对接其他分站产品&#xff0c;分站客服可自定义&#xff0c;支持限定优惠。 源码下载&a…

matlab--legend利用for循环添加图例

第一种方法 %% 第一种方法 R 1:4; THETA1 atand(R./1.8); legend_name {}; for i 1:4THETA atand(R(i)./1.8);intTheta floor(THETA);R_THERA 1.8 - (R(i)./tand(intTheta-10:intTheta10));R_THERA1 1.8 - (R(i)/tand(intTheta));plot(R_THERA);grid on;hold onlegend…

Git之repo sync -c与repo sync -dc用法区别(四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

了解Linux中的shell脚本

目录 1、什么是shell 2、编写第一个shell文件 3、shell的权限 4、变量 5、 shell传递参数 6、shell数组 7、shell基本运算符 7.1 算术运算符 7.2 关系运算符 7.3 布尔运算符 7.4 逻辑运算符 7.5 字符串运算符 8、控制语句 8.1 if 8.2 for 8.3 while语句 9、其他 1、…

C++~~string模拟实现(3)

目录 1.传统写法和现代写法 2.对于流提取的优化 3.简单机制了解 4.string类的几个构造函数总结 4.1基本用法 4.2两个赋值方式 4.3拷贝构造 4.4获取字符 4.5一个容易混淆的对比 4.6创建对象 1.传统写法和现代写法 &#xff08;1&#xff09;上面的代码里面的左边部分是…

排序---归并排序

归并排序 一、定义二、实现原理三、代码实现 一、定义 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有…

ES中聚合查询之date_histogram查询出现key_as_string 和 key含义

ES中聚合查询之date_histogram查询出现key_as_string 和 key含义 DSL语句 #实例 GET /capture_features_202407/_search {"query": {"bool": {"must": [{"terms": {"plateNo": ["汉A00001"]}},{"range&quo…

【C++】——初识模版

文章目录 前言函数模版函数模版的原理函数模版的实例化 类模版类模版的实例化 前言 当我们使用一个通用的函数&#xff1a; //为每一个类型都编写一个重载版本 void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& …