JDK 22 新特性详解
· 阅读需 8 分钟
Java 22 作为一个非长期支持版本(non-LTS),于2024年3月19日正式发布。这个版本继续改进了一些预览特性,并带来了一些新的改进。让我们一起来了解这些新特性。
1. 字符串模板(第二次预览)
字符串模板的改进版本:
public class StringTemplateDemo {
public static void main(String[] args) {
// 基本用法
String name = "张三";
int age = 25;
String info = STR."用户 \{name} 的年龄是 \{age}";
System.out.println(info);
// 使用 JSON 处理器
record Person(String name, int age, String city) {}
var person = new Person("李四", 30, "北京");
String json = JSON."""
{
"name": "\{person.name()}",
"age": \{person.age()},
"city": "\{person.city()}",
"timestamp": "\{java.time.LocalDateTime.now()}"
}
""";
System.out.println(json);
// 使用 SQL 处理器
String tableName = "users";
String condition = "active = 1";
int limit = 10;
String sql = SQL."""
SELECT *
FROM \{tableName}
WHERE \{condition}
LIMIT \{limit}
""";
System.out.println(sql);
// 使用 FMT 处理器进行格式化
double price = 12345.6789;
String formatted = FMT."价格:%.2f 元\{price}";
System.out.println(formatted);
// 嵌套模板
var items = List.of("苹果", "香蕉", "橙子");
String html = STR."""
<ul>
\{items.stream()
.map(item -> STR."<li>\{item}</li>")
.collect(Collectors.joining("\n "))}
</ul>
""";
System.out.println(html);
// 条件模板
boolean isAdmin = true;
String role = STR."用户角色:\{isAdmin ? "管理员" : "普通用户"}";
System.out.println(role);
// 使用自定义处理器
String log = LogTemplate."""
[%level] \{LocalDateTime.now()}: \{message}
""";
}
// 自定义模板处理器
static class LogTemplate {
public static String process(StringTemplate template) {
return template.interpolate()
.replace("%level", "INFO");
}
}
}
改进特性:
- 更多内置处理器
- 改进的语法支持
- 更好的性能
- 增强的类型安全
2. 未命名变量和模式(第二次预览)
未命名变量和模式的改进:
public class UnnamedPatternsDemo {
public static void main(String[] args) {
// 在记录模式中使用未命名变量
var point = new Point(10, 20);
if (point instanceof Point(var x, _)) {
System.out.println("x 坐标:" + x);
}
// 在方法参数中使用未命名变量
processCoordinates(10, _);
// 在 lambda 表达式中使用
List<Point> points = List.of(
new Point(1, 1),
new Point(2, 2),
new Point(3, 3)
);
points.stream()
.filter(Point(var x, _) -> x > 1)
.forEach(System.out::println);
// 在 switch 表达式中使用
processShape(new Circle(new Point(0, 0), 5));
processShape(new Rectangle(new Point(0, 0), 10, _));
}
// 使用未命名变量的方法
static void processCoordinates(int x, int _) {
System.out.println("处理 x 坐标:" + x);
}
// 在 switch 中使用未命名模式
static void processShape(Shape shape) {
var result = switch (shape) {
case Circle(Point(var x, _), var r) ->
STR."圆形:中心x=\{x}, 半径=\{r}";
case Rectangle(Point(_, var y), var w, _) ->
STR."矩形:y=\{y}, 宽度=\{w}";
};
System.out.println(result);
}
// 在构造函数中使用未命名参数
record ColoredPoint(Point point, Color color) {
ColoredPoint(int x, int _) {
this(new Point(x, 0), new Color(0, 0, 0));
}
}
// 在接口中使用未命名参数
interface ShapeProcessor {
void process(Shape shape, Color _);
}
// 数据类型定义
record Point(int x, int y) {}
record Color(int r, int g, int b) {}
sealed interface Shape permits Circle, Rectangle {}
record Circle(Point center, double radius) implements Shape {}
record Rectangle(Point topLeft, int width, int height) implements Shape {}
}
改进:
- 更广泛的使用场景
- 更好的编译器支持
- 改进的类型推断
- 与模式匹配的更好整合
3. 区域化改进
增强的区域化支持:
public class LocalizationDemo {
public static void main(String[] args) {
// 使用新的区域化 API
var locale = Locale.of("zh", "CN");
// 日期时间格式化
var dateTime = LocalDateTime.now();
var formatter = DateTimeFormatter.ofLocalizedDateTime(
FormatStyle.FULL
).withLocale(locale);
System.out.println("当前时间:" + dateTime.format(formatter));
// 数字格式化
var number = 12345.6789;
var numberFormat = NumberFormat.getInstance(locale);
System.out.println("格式化数字:" + numberFormat.format(number));
// 货币格式化
var money = 9876.54;
var currencyFormat = NumberFormat.getCurrencyInstance(locale);
System.out.println("货币金额:" + currencyFormat.format(money));
// 使用 Resource Bundle
var bundle = ResourceBundle.getBundle("messages", locale);
System.out.println("欢迎消息:" + bundle.getString("welcome"));
// 日历系统
var calendar = Calendar.getInstance(locale);
System.out.println("当前日期:" + calendar.getTime());
// 排序规则
var collator = Collator.getInstance(locale);
var words = List.of("苹果", "香蕉", "橙子");
words.stream()
.sorted(collator)
.forEach(System.out::println);
}
// 多语言支持示例
static class MultiLanguageSupport {
private final Map<Locale, ResourceBundle> bundles;
public MultiLanguageSupport() {
bundles = new HashMap<>();
bundles.put(Locale.CHINESE,
ResourceBundle.getBundle("messages", Locale.CHINESE));
bundles.put(Locale.ENGLISH,
ResourceBundle.getBundle("messages", Locale.ENGLISH));
}
public String getMessage(String key, Locale locale) {
return bundles.getOrDefault(locale, bundles.get(Locale.ENGLISH))
.getString(key);
}
}
// 格式化工具类
static class FormattingUtils {
public static String formatDateTime(
LocalDateTime dateTime,
Locale locale,
FormatStyle style
) {
var formatter = DateTimeFormatter
.ofLocalizedDateTime(style)
.withLocale(locale);
return dateTime.format(formatter);
}
public static String formatCurrency(
double amount,
Locale locale
) {
var format = NumberFormat.getCurrencyInstance(locale);
return format.format(amount);
}
}
}
改进:
- 更好的区域支持
- 改进的格式化
- 增强的资源绑定
- 更好的国际化支持
4. 其他改进
4.1 性能优化
public class PerformanceDemo {
// 改进的字符串处理
static void stringProcessing() {
var sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(STR."项目-\{i}");
}
System.out.println(sb.toString());
}
// 改进的集合处理
static void collectionProcessing() {
var list = new ArrayList<String>();
list.addAll(List.of("A", "B", "C"));
// 使用序列化集合的新方法
var first = list.getFirst();
var last = list.getLast();
// 并行流优化
list.parallelStream()
.map(String::toLowerCase)
.forEach(System.out::println);
}
// 改进的文件操作
static void fileProcessing() throws IOException {
var path = Path.of("test.txt");
// 使用新的文件 API
Files.writeString(path, "测试内容");
var content = Files.readString(path);
// 使用 Channel
try (var channel = FileChannel.open(path)) {
var buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
}
}
}
4.2 安全性改进
public class SecurityDemo {
// 改进的加密支持
static void cryptographyExample() throws Exception {
// 使用更强的加密算法
var keyPair = KeyPairGenerator.getInstance("RSA")
.generateKeyPair();
// 数字签名
var signature = Signature.getInstance("SHA256withRSA");
signature.initSign(keyPair.getPrivate());
// 安全随机数
var random = SecureRandom.getInstanceStrong();
var bytes = new byte[16];
random.nextBytes(bytes);
}
// 改进的权限检查
static void securityChecks() {
var manager = System.getSecurityManager();
if (manager != null) {
manager.checkPermission(new RuntimePermission("exitVM"));
}
// 访问控制
AccessController.doPrivileged(
(PrivilegedAction<Void>) () -> {
// 特权操作
return null;
}
);
}
}
4.3 工具改进
public class ToolingDemo {
// JDK 工具改进示例
static void toolingExamples() {
// 使用 jpackage 创建应用程序包
// jpackage --name myapp --input target/ --main-jar myapp.jar
// 使用 jwebserver 启动 Web 服务器
// jwebserver -p 8000
// 使用 jshell 进行交互式编程
// jshell> var x = 10
// jshell> System.out.println(x)
}
}
总结
JDK 22 虽然是一个非 LTS 版本,但它带来了一些重要的改进,特别是在字符串模板和未命名变量方面的优化,以及区域化支持的增强。这些改进为开发者提供了更好的工具和更高的开发效率。
对于开发者来说,建议:
- 探索字符串模板的新特性
- 使用未命名变量简化代码
- 利用改进的区域化支持
- 关注性能优化机会
- 保持对预览特性的跟进
虽然这是一个过渡版本,但其中的改进为 Java 的未来发展提供了重要的基础。建议在开发环境中尝试这些新特性,为未来的 LTS 版本做好准备。