Java 21 新特性详解(Record、Pattern Matching、Switch 改进)
引言
Java 21于2023年9月发布,是自Java 8和Java 11以来的又一个LTS版本。它不仅延续了Java语言的演进方向,还引入了多项重要的语言特性,显著提升了代码的简洁性、可读性和性能。本文将重点介绍Java 21中最重要的几个特性。
Record 模式匹配
Record 模式匹配基础
Record模式匹配是Java 21中最引人注目的特性之一,它扩展了Java 16引入的Record功能,使其能够与模式匹配结合使用。
// Record定义
public record Person(String name, int age, String email) {
}
public record Employee(String name, int age, String email, String department) extends Person(name, age, email) {
}
public record Student(String name, int age, String email, String major) extends Person(name, age, email) {
}
// 传统的类型检查和转换
public class TraditionalPatternMatching {
public static void processPerson(Object obj) {
if (obj instanceof Person) {
Person person = (Person) obj;
System.out.println("Name: " + person.name() + ", Age: " + person.age());
}
}
// 更复杂的嵌套结构处理
public static void processNestedStructure(Object obj) {
if (obj instanceof Employee) {
Employee emp = (Employee) obj;
if (emp.department() != null && emp.department().length() > 0) {
System.out.println("Employee: " + emp.name() + " works in " + emp.department());
}
}
}
}
// 使用Record模式匹配
public class RecordPatternMatching {
public static void processPerson(Object obj) {
switch (obj) {
case Person p -> System.out.println("Name: " + p.name() + ", Age: " + p.age());
case Employee e -> System.out.println("Employee: " + e.name() + " in " + e.department());
case Student s -> System.out.println("Student: " + s.name() + " studying " + s.major());
default -> System.out.println("Unknown type");
}
}
// 嵌套Record模式匹配
public static void processNestedRecord(Object obj) {
switch (obj) {
case Employee(String name, int age, String email, String department) ->
System.out.println("Employee: " + name + ", Dept: " + department);
case Student(var name, var age, var email, var major) ->
System.out.println("Student: " + name + ", Major: " + major);
default -> System.out.println("Not a Person subclass");
}
}
// 复杂的Record模式匹配示例
public static void complexPatternMatching(Object obj) {
switch (obj) {
case Person(String name, int age, String email) when age >= 18 ->
System.out.println("Adult: " + name + " (" + age + ")");
case Person(String name, int age, String email) when age < 18 ->
System.out.println("Minor: " + name + " (" + age + ")");
case Employee(String name, int age, String email, String dept) when "IT".equals(dept) ->
System.out.println("IT Employee: " + name);
case Student(String name, int age, String email, String major) when "Computer Science".equals(major) ->
System.out.println("CS Student: " + name);
default -> System.out.println("Other case");
}
}
}
Record模式匹配高级应用
public class AdvancedRecordPattern {
public record Address(String street, String city, String country) {
}
public record Company(String name, Address address) {
}
public record EmployeeWithAddress(String name, int age, Company company) {
}
// 嵌套Record模式匹配
public static void nestedPatternMatching(Object obj) {
switch (obj) {
case EmployeeWithAddress(String name, int age, Company(String companyName, Address(String street, String city, String country))) -> {
System.out.println("Employee: " + name);
System.out.println("Company: " + companyName);
System.out.println("Address: " + street + ", " + city + ", " + country);
}
default -> System.out.println("Not matched");
}
}
// 带条件的嵌套模式匹配
public static void conditionalNestedPattern(Object obj) {
switch (obj) {
case EmployeeWithAddress(var name, var age, Company(var compName, Address(var street, var city, var country)))
when city.equals("Beijing") -> {
System.out.println(name + " works in Beijing at " + compName);
}
case EmployeeWithAddress(var name, var age, var company)
when age > 30 -> {
System.out.println(name + " is a senior employee");
}
default -> System.out.println("Other case");
}
}
// 模式匹配与Stream API结合
public static void streamWithPatterns() {
List<Object> objects = List.of(
new Person("Alice", 25, "alice@example.com"),
new Employee("Bob", 30, "bob@example.com", "IT"),
new Student("Charlie", 20, "charlie@example.com", "Math")
);
// 使用模式匹配过滤和转换
List<String> results = objects.stream()
.map(obj -> switch (obj) {
case Person p -> "Person: " + p.name();
case Employee e -> "Employee: " + e.name() + " (" + e.department() + ")";
case Student s -> "Student: " + s.name() + " (" + s.major() + ")";
default -> "Unknown";
})
.filter(result -> result.contains("IT") || result.contains("Math"))
.toList();
results.forEach(System.out::println);
}
}
Switch 表达式改进
Switch 模式匹配增强
Java 21进一步增强了Switch表达式,支持更复杂的模式匹配场景。
public class EnhancedSwitchPatterns {
// 传统Switch与新Switch对比
public static String traditionalSwitch(Object obj) {
if (obj instanceof String) {
String str = (String) obj;
if (str.length() > 5) {
return "Long string";
} else {
return "Short string";
}
} else if (obj instanceof Integer) {
Integer num = (Integer) obj;
if (num > 100) {
return "Large number";
} else {
return "Small number";
}
} else {
return "Other type";
}
}
// 使用增强的Switch表达式
public static String enhancedSwitch(Object obj) {
return switch (obj) {
case String s when s.length() > 5 -> "Long string: " + s;
case String s when s.length() <= 5 -> "Short string: " + s;
case Integer i when i > 100 -> "Large number: " + i;
case Integer i when i <= 100 -> "Small number: " + i;
case null -> "Null value";
default -> "Other type: " + obj.getClass().getSimpleName();
};
}
// 多重模式匹配
public static void multiplePatternMatching(Object obj) {
switch (obj) {
case String s && s.startsWith("A") -> System.out.println("String starts with A: " + s);
case String s && s.endsWith("z") -> System.out.println("String ends with z: " + s);
case Integer i && i % 2 == 0 -> System.out.println("Even number: " + i);
case Integer i && i % 2 != 0 -> System.out.println("Odd number: " + i);
case Person p && p.age() > 18 -> System.out.println("Adult person: " + p.name());
case Person p && p.age() <= 18 -> System.out.println("Minor person: " + p.name());
default -> System.out.println("No specific pattern matched");
}
}
// Switch表达式与泛型结合
public static <T> String genericSwitch(T obj) {
return switch (obj) {
case String s -> "String: " + s;
case Integer i -> "Integer: " + i;
case Double d -> "Double: " + d;
case List<?> list -> "List with " + list.size() + " elements";
case Map<?, ?> map -> "Map with " + map.size() + " entries";
default -> "Unknown type: " + obj.getClass().getSimpleName();
};
}
// Switch表达式返回复杂对象
public record Result<T>(boolean success, T data, String message) {
}
public static <T> Result<T> processWithSwitch(Object input, Class<T> expectedType) {
return switch (input) {
case String s when expectedType == String.class ->
new Result<>(true, (T) s, "Successfully processed string");
case Integer i when expectedType == Integer.class ->
new Result<>(true, (T) i, "Successfully processed integer");
case Person p when expectedType == Person.class ->
new Result<>(true, (T) p, "Successfully processed person");
default -> new Result<>(false, null, "Type mismatch");
};
}
}
Switch表达式性能优化
public class SwitchPerformance {
// 传统方法性能测试
public static String traditionalMethod(Object obj) {
if (obj instanceof String) return "String";
if (obj instanceof Integer) return "Integer";
if (obj instanceof Double) return "Double";
if (obj instanceof Boolean) return "Boolean";
if (obj instanceof List) return "List";
return "Other";
}
// Switch表达式性能测试
public static String switchExpression(Object obj) {
return switch (obj) {
case String s -> "String";
case Integer i -> "Integer";
case Double d -> "Double";
case Boolean b -> "Boolean";
case List<?> l -> "List";
default -> "Other";
};
}
// 性能比较方法
public static void performanceComparison() {
List<Object> testObjects = List.of(
"test", 123, 45.6, true, List.of(1, 2, 3)
);
// 测试传统方法
long start = System.nanoTime();
for (int i = 0; i < 100000; i++) {
for (Object obj : testObjects) {
traditionalMethod(obj);
}
}
long traditionalTime = System.nanoTime() - start;
// 测试Switch表达式
start = System.nanoTime();
for (int i = 0; i < 100000; i++) {
for (Object obj : testObjects) {
switchExpression(obj);
}
}
long switchTime = System.nanoTime() - start;
System.out.println("Traditional method time: " + traditionalTime / 1_000_000 + " ms");
System.out.println("Switch expression time: " + switchTime / 1_000_000 + " ms");
}
}
Record 增强功能
Record 验证和规范化
public class EnhancedRecordFeatures {
// 带验证的Record
public record ValidatedPerson(String name, int age) {
public ValidatedPerson {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("Name cannot be null or blank");
}
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Age must be between 0 and 150");
}
}
}
// 带默认值的Record
public record DefaultPerson(String name, int age, String email) {
public DefaultPerson {
name = name != null ? name : "Unknown";
age = age > 0 ? age : 0;
email = email != null ? email : "no-email@example.com";
}
}
// Record方法增强
public record EnhancedPerson(String firstName, String lastName, int age) {
public String fullName() {
return firstName + " " + lastName;
}
public boolean isAdult() {
return age >= 18;
}
public EnhancedPerson withAge(int newAge) {
return new EnhancedPerson(firstName, lastName, newAge);
}
public EnhancedPerson withFirstName(String newFirstName) {
return new EnhancedPerson(newFirstName, lastName, age);
}
}
// 静态工厂方法
public record PersonFactory(String name, int age) {
public static PersonFactory adult(String name, int age) {
if (age < 18) {
throw new IllegalArgumentException("Must be adult");
}
return new PersonFactory(name, age);
}
public static PersonFactory child(String name, int age) {
if (age >= 18) {
throw new IllegalArgumentException("Must be child");
}
return new PersonFactory(name, age);
}
}
// 泛型Record
public record GenericRecord<T>(T value, Class<T> type) {
public GenericRecord {
if (value == null) {
throw new IllegalArgumentException("Value cannot be null");
}
}
public boolean isType(Class<?> expectedType) {
return type.equals(expectedType);
}
}
}
Record 继承和多态
public class RecordInheritance {
// 抽象Record(实际上Java不支持抽象Record,但可以通过接口模拟)
public interface Identifiable {
String id();
}
public record User(String id, String name, String email) implements Identifiable {
}
public record Admin(String id, String name, String email, Set<String> permissions)
implements Identifiable {
}
// Record多态处理
public static void processIdentifiable(Identifiable obj) {
System.out.println("Processing: " + obj.id());
switch (obj) {
case User user -> System.out.println("User: " + user.name());
case Admin admin -> System.out.println("Admin: " + admin.name() +
" with permissions: " + admin.permissions());
default -> System.out.println("Unknown type");
}
}
// Record层次结构
public sealed interface Shape permits Circle, Rectangle, Triangle {
}
public record Circle(double radius) implements Shape {
public double area() {
return Math.PI * radius * radius;
}
}
public record Rectangle(double width, double height) implements Shape {
public double area() {
return width * height;
}
}
public record Triangle(double base, double height) implements Shape {
public double area() {
return 0.5 * base * height;
}
}
// 使用密封接口的Switch表达式
public static double calculateArea(Shape shape) {
return switch (shape) {
case Circle c -> c.area();
case Rectangle r -> r.area();
case Triangle t -> t.area();
};
}
}
实际应用场景
数据处理管道
public class DataProcessingPipeline {
public record InputData(String id, String data, String type) {
}
public record ProcessedData(String id, Object processed, String type, long timestamp) {
}
public record OutputResult(String id, String status, Object result) {
}
// 数据处理管道
public static OutputResult processPipeline(InputData input) {
return switch (input) {
case InputData(String id, String data, "JSON") -> {
// JSON处理逻辑
var processed = parseJson(data);
yield new OutputResult(id, "SUCCESS",
new ProcessedData(id, processed, "JSON", System.currentTimeMillis()));
}
case InputData(String id, String data, "XML") -> {
// XML处理逻辑
var processed = parseXml(data);
yield new OutputResult(id, "SUCCESS",
new ProcessedData(id, processed, "XML", System.currentTimeMillis()));
}
case InputData(String id, String data, "TEXT") -> {
// 文本处理逻辑
var processed = processData(data);
yield new OutputResult(id, "SUCCESS",
new ProcessedData(id, processed, "TEXT", System.currentTimeMillis()));
}
default -> new OutputResult(input.id(), "ERROR", "Unsupported type: " + input.type());
};
}
private static Object parseJson(String json) {
// 简化的JSON解析
return Map.of("parsed", json, "type", "json");
}
private static Object parseXml(String xml) {
// 简化的XML解析
return Map.of("parsed", xml, "type", "xml");
}
private static Object processData(String data) {
return data.toUpperCase();
}
// 批量处理
public static List<OutputResult> processBatch(List<InputData> inputs) {
return inputs.stream()
.map(DataProcessingPipeline::processPipeline)
.filter(result -> "SUCCESS".equals(result.status()))
.toList();
}
}
配置管理
public class ConfigurationManagement {
public record DatabaseConfig(String url, String username, String password, int maxConnections) {
}
public record CacheConfig(String provider, int maxSize, long ttl) {
}
public record AppConfig(DatabaseConfig database, CacheConfig cache, Map<String, String> properties) {
}
// 配置验证
public static void validateConfig(AppConfig config) {
switch (config) {
case AppConfig(
DatabaseConfig(String url, String user, String pass, int maxConn),
CacheConfig(String provider, int maxSize, long ttl),
Map<String, String> props
) when url != null && !url.isBlank() -> {
System.out.println("Valid database configuration");
}
case AppConfig(var db, var cache, var props) -> {
System.out.println("Invalid configuration detected");
// 可以进一步细分验证逻辑
}
}
}
// 配置转换
public static Map<String, Object> configToMap(AppConfig config) {
return switch (config) {
case AppConfig(
DatabaseConfig(String url, String user, String pass, int maxConn),
CacheConfig(String provider, int maxSize, long ttl),
Map<String, String> props
) -> Map.of(
"database", Map.of("url", url, "maxConnections", maxConn),
"cache", Map.of("provider", provider, "maxSize", maxSize),
"properties", props
);
};
}
// 配置更新
public static AppConfig updateDatabaseConfig(AppConfig current, DatabaseConfig newDb) {
return switch (current) {
case AppConfig(var oldDb, var cache, var props) ->
new AppConfig(newDb, cache, props);
};
}
}
事件处理系统
public class EventProcessingSystem {
public sealed interface Event permits UserEvent, SystemEvent, ErrorEvent {
}
public record UserEvent(String userId, String action, Map<String, Object> data) implements Event {
}
public record SystemEvent(String systemId, String eventType, long timestamp) implements Event {
}
public record ErrorEvent(String errorId, String message, Throwable cause) implements Event {
}
// 事件处理器
public static void handleEvent(Event event) {
switch (event) {
case UserEvent(String userId, String action, Map<String, Object> data) -> {
System.out.println("User " + userId + " performed " + action);
data.forEach((key, value) ->
System.out.println(" " + key + ": " + value));
}
case SystemEvent(String systemId, String eventType, long timestamp) -> {
System.out.println("System " + systemId + " event: " + eventType);
System.out.println("Timestamp: " + new Date(timestamp));
}
case ErrorEvent(String errorId, String message, Throwable cause) -> {
System.err.println("Error " + errorId + ": " + message);
if (cause != null) {
cause.printStackTrace();
}
}
}
}
// 事件过滤和处理
public static void processFilteredEvents(List<Event> events, String eventType) {
events.stream()
.filter(event -> switch (event) {
case UserEvent e -> "USER".equals(eventType);
case SystemEvent e -> "SYSTEM".equals(eventType);
case ErrorEvent e -> "ERROR".equals(eventType);
})
.forEach(EventProcessingSystem::handleEvent);
}
// 事件聚合
public static Map<String, List<Event>> groupEventsByType(List<Event> events) {
Map<String, List<Event>> grouped = new HashMap<>();
for (Event event : events) {
String type = switch (event) {
case UserEvent e -> "USER";
case SystemEvent e -> "SYSTEM";
case ErrorEvent e -> "ERROR";
};
grouped.computeIfAbsent(type, k -> new ArrayList<>()).add(event);
}
return grouped;
}
}
性能和最佳实践
性能优化建议
public class PerformanceBestPractices {
// 避免不必要的对象创建
public static String processWithSwitchOptimized(Object obj) {
return switch (obj) {
case String s when s.length() > 10 -> s.substring(0, 10) + "...";
case String s -> s; // 直接返回,避免创建新对象
case Integer i -> String.valueOf(i); // 使用valueOf缓存小整数
default -> obj.toString();
};
}
// 使用Switch表达式的性能优势
public static boolean isValidInput(Object input) {
return switch (input) {
case String s -> !s.isBlank() && s.length() <= 100;
case Integer i -> i > 0 && i < 10000;
case Double d -> d > 0.0 && d < 1000.0;
case null -> false;
default -> true;
};
}
// Record的不可变性优势
public record ImmutableConfig(String host, int port, boolean ssl) {
public ImmutableConfig {
host = host != null ? host : "localhost";
port = port > 0 ? port : 8080;
ssl = ssl;
}
public ImmutableConfig withHost(String newHost) {
return new ImmutableConfig(newHost, port, ssl);
}
public ImmutableConfig withPort(int newPort) {
return new ImmutableConfig(host, newPort, ssl);
}
}
// 使用Record构建器模式
public static class ConfigBuilder {
private String host = "localhost";
private int port = 8080;
private boolean ssl = false;
public ConfigBuilder host(String host) {
this.host = host;
return this;
}
public ConfigBuilder port(int port) {
this.port = port;
return this;
}
public ConfigBuilder ssl(boolean ssl) {
this.ssl = ssl;
return this;
}
public ImmutableConfig build() {
return new ImmutableConfig(host, port, ssl);
}
}
}
代码可读性提升
public class ReadabilityEnhancements {
// 清晰的业务逻辑表达
public static String determineUserStatus(Object user) {
return switch (user) {
case Person(String name, int age, String email) when age >= 18 && email.contains("@") ->
"Valid adult user: " + name;
case Person(String name, int age, String email) when age < 18 ->
"Minor user: " + name;
case Person(String name, int age, String email) when !email.contains("@") ->
"Invalid email for: " + name;
default -> "Unknown user type";
};
}
// 类型安全的多态处理
public static void handlePayment(Object payment) {
switch (payment) {
case CreditCardPayment(String number, double amount, String cvv) when amount > 0 -> {
System.out.println("Processing credit card payment: " + amount);
// 实际支付处理逻辑
}
case PayPalPayment(String email, double amount) when amount > 0 -> {
System.out.println("Processing PayPal payment: " + amount);
// 实际支付处理逻辑
}
case BankTransfer(String account, double amount) when amount > 0 -> {
System.out.println("Processing bank transfer: " + amount);
// 实际支付处理逻辑
}
default -> System.out.println("Invalid payment method");
}
}
// 复杂条件的清晰表达
public static String analyzeRisk(Object client) {
return switch (client) {
case Person(String name, int age, String email) when age > 65 ->
"High risk: Senior citizen";
case Person(String name, int age, String email) when age < 18 ->
"High risk: Minor";
case Employee e when e.department().equals("Finance") ->
"Medium risk: Finance employee";
case Student s when s.major().equals("Computer Science") ->
"Low risk: CS student";
default -> "Standard risk";
};
}
}
迁移和兼容性考虑
public class MigrationConsiderations {
// 向后兼容的实现
public static void legacyMethod(Object obj) {
// 旧的实现方式
if (obj instanceof String) {
String str = (String) obj;
System.out.println("Legacy string handling: " + str);
} else if (obj instanceof Integer) {
Integer num = (Integer) obj;
System.out.println("Legacy number handling: " + num);
}
}
// 新的实现方式
public static void modernMethod(Object obj) {
switch (obj) {
case String s -> System.out.println("Modern string handling: " + s);
case Integer i -> System.out.println("Modern number handling: " + i);
default -> System.out.println("Unknown type");
}
}
// 渐进式迁移策略
public static void hybridApproach(Object obj) {
if (obj instanceof String str && str.length() > 100) {
// 对于特殊情况进行传统处理
legacyMethod(obj);
} else {
// 其他情况使用新模式
modernMethod(obj);
}
}
}
总结
Java 21的Record模式匹配、Switch表达式改进等新特性显著提升了代码的简洁性和可读性。这些特性不仅减少了样板代码,还提供了更强的类型安全和更清晰的业务逻辑表达。开发者应该积极采用这些新特性,以编写更现代、更高效的Java代码。
关于作者
🌟 我是suxiaoxiang,一位热爱技术的开发者
💡 专注于Java生态和前沿技术分享
🚀 持续输出高质量技术内容
如果这篇文章对你有帮助,请支持一下:
👍 点赞
⭐ 收藏
👀 关注
您的支持是我持续创作的动力!感谢每一位读者的关注与认可!