Java 21 新特性的扫盲级别初体验
代码探险家_cool 2024-08-10 09:35:01 阅读 80
一、前言
JDK 21 于 2023 年 9 月发布,作为目前讨论热度最高的JDK,虽然大家都开玩笑说<code>你发任你发,我用Java8,但是作为一个Javaer,对JDK21的新特性还是要有所了解的。
以下是 JDK 21 的新功能列表:
虚拟线程序列集合记录模式字符串模板(预览)未命名模式和变量(预览)未命名类和实例主要方法(预览)作用域值(预览)结构化并发(预览)
JDK21下载地址:JDK官网
安装过程在这里就不赘述了,正常【下一步】就行了。
二、新特性体验
1. switch 模式匹配
可以通过switch表达式和语句的模式匹配来增强Java编程语言,可以针对多个模式测试表达式,每个模式都有一个特定的操作,从而可以简洁、安全地表达复杂的面向数据的查询。
1.1 支持返回值,不用写break
示例代码:
<code>public class SwitchTest { -- -->
public static void main(String[] args) {
String unit = "cm";
String str = switch (unit) {
case "cm" -> "厘米";
case "m" -> "米";
case "mm" -> "毫米";
case "km" -> "千米";
default -> "错误";
};
System.out.println(str);
}
}
测试结果:
注意:如果执行结果乱码,可以参考如下操作进行:
增加VM参数
修改文件编码
1.2 如果需要执行多行代码再返回,可使用yield关键字
示例代码:
<code>public class SwitchTest { -- -->
public static void main(String[] args) {
String unit = "cm";
String str = switch (unit) {
case "cm" -> {
System.out.println("我在测试呢...");
yield "厘米";
}
case "m" -> "米";
case "mm" -> "毫米";
case "km" -> "千米";
default -> "错误";
};
System.out.println(str);
}
}
1.3 多值匹配
示例代码:
public class SwitchTest {
public static void main(String[] args) {
String unit = "cm";
String str = switch (unit) {
case "cm", "m" -> "厘米";
case "mm" -> "毫米";
case "km" -> "千米";
default -> "错误";
};
System.out.println(str);
}
}
1.4 null值处理
示例代码:
public class SwitchTest {
public static void main(String[] args) {
String unit = null;
String str = switch (unit) {
case "cm", "m" -> "厘米";
case "mm" -> "毫米";
case "km" -> "千米";
case null -> "未知";
default -> "错误";
};
System.out.println(str);
}
}
1.5 匹配增强
示例代码:
public class SwitchTest {
public static void main(String[] args) {
Double obj = 0.0d;
String str = 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);
default -> obj.toString();
};
System.out.println(str);
}
}
2. 记录模式
记录模式,也就是记录模式匹配,英文为“Record Patterns”,记录模式匹配是指自动匹配Record记录类,从而简化代码。Record记录会自动生成了构造函数、getter、equals、hashCode、toString等方法,简化代码的编写,类似于lombok插件的@Data注解,但是对象属性只读,只有get方法,没有set方法。
使用class
public class User {
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
使用record
public record User(String name, Integer age) {
}
3. 字符串模板
示例代码:
public class StrTest {
public static void main(String[] args) {
String name = "JDK21";
String message = STR."Hello \{name}!";
System.out.println(message);
}
}
注意这是预览功能,默认禁用,我们需要使用--enable-preview
启用字符串模板。
在Idea中,我们需要额外设置:
<code>--enable-preview --source 21 -Xlint:preview
4. 顺序集合
SequencedSet 接口对于具有有序元素的 Set 非常有用,特别是当您必须执行某些操作(例如检索或删除第一个或最后一个索引处的元素)时。它还提供了一种反转元素的方法。
List
import java.util.LinkedHashSet;
import java.util.SequencedSet;
public class ListTest {
public static void main(String[] args) {
SequencedSet<String> values = new LinkedHashSet<>();
values.add("one");
values.add("two");
System.out.println(values); // [one, two]
values.addFirst("zero");
System.out.println(values); // [zero, one, two]
values.addFirst("one");
System.out.println(values); // [one, zero, two]
values.addLast("three");
System.out.println(values); // [one, zero, two, three]
SequencedSet<String> reversedSet = values.reversed();
System.out.println(reversedSet); // [three, two, zero, one]
}
}
Map
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SequencedMap;
public class MapTest {
public static void main(String[] args) {
SequencedMap<String, Integer> myMap = new LinkedHashMap<>();
myMap.put("one", 1);
myMap.put("two", 2);
System.out.println(myMap); // {one=1, two=2}
Map.Entry<String, Integer> firstEntry = myMap.firstEntry();
System.out.println(firstEntry); // one=1
Map.Entry<String, Integer> lastEntry = myMap.lastEntry();
System.out.println(lastEntry); // two=2
myMap.putFirst("zero", 0);
System.out.println(myMap); // {zero=0, one=1, two=2}
myMap.putFirst("one", -1);
System.out.println(myMap); // {one=-1, zero=0, two=2}
Map.Entry<String, Integer> polledFirstEntry = myMap.pollFirstEntry();
System.out.println(polledFirstEntry); // one=-1
System.out.println(myMap); // {zero=0, two=2}
SequencedMap<String, Integer> reversedMap = myMap.reversed();
System.out.println(reversedMap); // {two=2, zero=0}
}
}
5. 虚拟线程
虚拟线程是Jdk21的重头戏,从 Java 代码的角度来看,虚拟线程感觉就像普通线程,但它们没有 1:1 映射到操作系统/平台线程。它是从虚拟线程到载体线程进而到操作系统线程的M:N映射。
虚拟线程的一些优点:
提高应用程序吞吐量
提高应用程序可用性
减少内存消耗
示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class VirtualThreadsTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
for (int i = 0; i < 10; i++) {
int taskId = i;
executor.execute(() -> {
System.out.println("Task " + taskId + " is running on virtual thread: " + Thread.currentThread().getName());
});
}
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
}
}
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。