跳到主要内容

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");
}
}
}
java

改进特性:

  • 更多内置处理器
  • 改进的语法支持
  • 更好的性能
  • 增强的类型安全

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 {}
}
java

改进:

  • 更广泛的使用场景
  • 更好的编译器支持
  • 改进的类型推断
  • 与模式匹配的更好整合

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);
}
}
}
java

改进:

  • 更好的区域支持
  • 改进的格式化
  • 增强的资源绑定
  • 更好的国际化支持

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);
}
}
}
java

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;
}
);
}
}
java

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)
}
}
java

总结

JDK 22 虽然是一个非 LTS 版本,但它带来了一些重要的改进,特别是在字符串模板和未命名变量方面的优化,以及区域化支持的增强。这些改进为开发者提供了更好的工具和更高的开发效率。

对于开发者来说,建议:

  1. 探索字符串模板的新特性
  2. 使用未命名变量简化代码
  3. 利用改进的区域化支持
  4. 关注性能优化机会
  5. 保持对预览特性的跟进

虽然这是一个过渡版本,但其中的改进为 Java 的未来发展提供了重要的基础。建议在开发环境中尝试这些新特性,为未来的 LTS 版本做好准备。