JavaGuide 官方网站:javaguide.cn
JavaGuide 官方星球:JavaGuide知识星球
真快啊,国内 JDK8 还是主流,这 JDK22 都已经来了!
不同于去年发布的 JDK21,JDK22 是非长期支持版本。所以,生产项目要想体验新特性,还是建议 JDK21,那是真香啊!
JDK 22 一共有 12 个新特性:
这篇文章会挑选其中较为重要的一些新特性进行介绍。
Java 程序可以通过该 API 与 Java 运行时之外的代码和数据进行互操作。通过高效地调用外部函数(即 JVM 之外的代码)和安全地访问外部内存(即不受 JVM 管理的内存),该 API 使 Java 程序能够调用本机库并处理本机数据,而不会像 JNI 那样危险和脆弱。
未命名模式和变量使得我们可以使用下划线 _
表示未命名的变量以及模式匹配时不使用的组件,旨在提高代码的可读性和可维护性。
未命名变量的典型场景是 try-with-resources
语句、 catch
子句中的异常变量和for
循环。当变量不需要使用的时候就可以使用下划线 _
代替,这样清晰标识未被使用的变量。
try (var _ = ScopedContext.acquire()) {
// No use of acquired resource
}
try { ... }
catch (Exception _) { ... }
catch (Throwable _) { ... }
for (int i = 0, _ = runOnce(); i < arr.length; i++) {
...
}
未命名模式是一个无条件的模式,并不绑定任何值。未命名模式变量出现在类型模式中。
if (r instanceof ColoredPoint(_, Color c)) { ... c ... }
switch (b) {
case Box(RedBall _), Box(BlueBall _) -> processBox(b);
case Box(GreenBall _) -> stopProcessing();
case Box(_) -> pickAnotherBox();
}
String Templates(字符串模板) 在 JDK21 中第一次预览,JDK22 是第二次预览。
String Templates 提供了一种更简洁、更直观的方式来动态构建字符串。通过使用占位符${}
,我们可以将变量的值直接嵌入到字符串中,而不需要手动处理。在运行时,Java 编译器会将这些占位符替换为实际的变量值。并且,表达式支持局部变量、静态/非静态字段甚至方法、计算结果等特性。
实际上,String Templates(字符串模板)再大多数编程语言中都存在:
"Greetings {{ name }}!"; //Angular
`Greetings ${ name }!`; //Typescript
$"Greetings { name }!" //Visual basic
f"Greetings { name }!" //Python
Java 在没有 String Templates 之前,我们通常使用字符串拼接或格式化方法来构建字符串:
//concatenation
message = "Greetings " + name + "!";
//String.format()
message = String.format("Greetings %s!", name); //concatenation
//MessageFormat
message = new MessageFormat("Greetings {0}!").format(name);
//StringBuilder
message = new StringBuilder().append("Greetings ").append(name).append("!").toString();
这些方法或多或少都存在一些缺点,比如难以阅读、冗长、复杂。
Java 使用 String Templates 进行字符串拼接,可以直接在字符串中嵌入表达式,而无需进行额外的处理:
String message = STR."Greetings \{name}!";
在上面的模板表达式中:
\{name}
为表达式,运行时,这些表达式将被相应的变量值替换。Java 目前支持三种模板处理器:
StringTemplate
对象,这个对象包含了模板中的文本和表达式的信息String name = "Lokesh";
//STR
String message = STR."Greetings \{name}.";
//FMT
String message = STR."Greetings %-12s\{name}.";
//RAW
StringTemplate st = RAW."Greetings \{name}.";
String message = STR.process(st);
除了 JDK 自带的三种模板处理器外,你还可以实现 StringTemplate.Processor
接口来创建自己的模板处理器。
我们可以使用局部变量、静态/非静态字段甚至方法作为嵌入表达式:
//variable
message = STR."Greetings \{name}!";
//method
message = STR."Greetings \{getName()}!";
//field
message = STR."Greetings \{this.name}!";
还可以在表达式中执行计算并打印结果:
int x = 10, y = 20;
String s = STR."\{x} + \{y} = \{x + y}"; //"10 + 20 = 30"
为了提高可读性,我们可以将嵌入的表达式分成多行:
String time = STR."The current time is \{
//sample comment - current time in HH:mm:ss
DateTimeFormatter
.ofPattern("HH:mm:ss")
.format(LocalTime.now())
}.";
向量计算由对向量的一系列操作组成。向量 API 用来表达向量计算,该计算可以在运行时可靠地编译为支持的 CPU 架构上的最佳向量指令,从而实现优于等效标量计算的性能。
向量 API 的目标是为用户提供简洁易用且与平台无关的表达范围广泛的向量计算。
这是对数组元素的简单标量计算:
void scalarComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f;
}
}
这是使用 Vector API 进行的等效向量计算:
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;
void vectorComputation(float[] a, float[] b, float[] c) {
int i = 0;
int upperBound = SPECIES.loopBound(a.length);
for (; i < upperBound; i += SPECIES.length()) {
// FloatVector va, vb, vc;
var va = FloatVector.fromArray(SPECIES, a, i);
var vb = FloatVector.fromArray(SPECIES, b, i);
var vc = va.mul(va)
.add(vb.mul(vb))
.neg();
vc.intoArray(c, i);
}
for (; i < a.length; i++) {
c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f;
}
}
这个改进使得 Stream API 可以支持自定义中间操作。
source.gather(a).gather(b).gather(c).collect(...)
👉推荐:
点击下方布局进入公众号
回复「PDF」 即可获取原创PDF技术面试手册
回复「学习路线」即可获取4w+字最新版Java学习路线回复「开源」即可获取优质Java开源项目合集免费分享无套路,有帮助点赞就好!