Java 8到Java 25语法更新详细介绍
一、Java 8(2014 年 3 月)—— 里程碑式的版本
Java 8 是 Java 历史上最具影响力的版本之一,引入了函数式编程的概念,彻底改变了 Java 的编程风格。
1. Lambda 表达式
Lambda 表达式允许将函数作为参数传递,简化了匿名内部类的编写。
语法格式:
(参数列表) -> { 代码块 }
// 或
(参数列表) -> 表达式
代码示例:
import java.util.Arrays;
import java.util.List;
public class LambdaDemo {
public static void main(String[] args) {
List<String> list = Arrays.asList("Java", "Lambda", "Stream");
// 传统匿名内部类
list.forEach(new java.util.function.Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
// Lambda表达式简化
list.forEach(s -> System.out.println(s));
// 更简洁的方法引用
list.forEach(System.out::println);
}
}
2. 方法引用
方法引用是 Lambda 表达式的语法糖,直接引用已有方法或构造器,使代码更简洁。
四种方法引用类型:
// 1. 静态方法引用
Function<Integer, String> f1 = String::valueOf;
// 2. 实例方法引用
String str = "Hello";
Supplier<Integer> s1 = str::length;
// 3. 特定类型方法引用
Comparator<String> c = String::compareToIgnoreCase;
// 4. 构造器引用
Supplier<List<String>> listSupplier = ArrayList::new;
3. 接口默认方法和静态方法
Java 8 允许在接口中定义默认方法和静态方法,解决了接口升级的兼容性问题。
代码示例:
public interface DataProcessor {
// 抽象方法
void processData();
// 默认方法
default void log() {
System.out.println("Processing data...");
}
// 静态方法
static void printVersion() {
System.out.println("DataProcessor v1.0");
}
}
public class DataProcessorImpl implements DataProcessor {
@Override
public void processData() {
System.out.println("Processing data implementation");
}
}
4. Stream API
Stream API 提供了声明式的集合数据处理方式,支持过滤、映射、聚合等操作。
代码示例:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamDemo {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 过滤偶数并映射为平方,然后收集为列表
List<Integer> evenSquares = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.collect(Collectors.toList());
System.out.println(evenSquares); // [4, 16, 36, 64, 100]
}
}
5. Optional 类
Optional 类用于优雅地处理 null 值,避免空指针异常。
代码示例:
import java.util.Optional;
public class OptionalDemo {
public static void main(String[] args) {
String name = null;
// 传统方式
if (name != null) {
System.out.println(name.length());
}
// Optional方式
Optional<String> optionalName = Optional.ofNullable(name);
optionalName.ifPresent(n -> System.out.println(n.length()));
// 提供默认值
String result = optionalName.orElse("Default Name");
System.out.println(result); // Default Name
}
}
6. 新的日期时间 API
Java 8 引入了 java.time 包,提供了更简洁、更安全的日期时间处理方式。
代码示例:
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DateTimeDemo {
public static void main(String[] args) {
// 获取当前日期时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 2026-03-02T16:00:00
// 格式化
String formatted = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(formatted); // 2026-03-02 16:00:00
// 日期计算
LocalDate tomorrow = LocalDate.now().plusDays(1);
System.out.println(tomorrow); // 2026-03-03
}
}
二、Java 9(2017 年 9 月)—— 模块化与接口增强
1. 模块系统(Project Jigsaw)
Java 9 引入了模块系统,解决了 "类路径地狱" 问题,允许开发者明确控制模块的依赖和访问权限。
模块定义示例(module-info.java):
module com.example.user {
requires java.base; // 依赖基础模块(默认隐式依赖)
requires com.example.common; // 依赖其他模块
exports com.example.user.service; // 导出可访问的包
exports com.example.user.model to com.example.web; // 定向导出
}
2. 接口私有方法
Java 9 允许在接口中定义私有方法,解决了接口中默认方法的代码复用问题。
代码示例:
public interface DataProcessor {
// 默认方法
default void process() {
readData();
analyzeData();
writeResult();
}
// 私有工具方法
private void readData() {
System.out.println("读取数据");
}
private void writeResult() {
System.out.println("写入结果");
}
// 抽象方法
void analyzeData();
}
3. 集合工厂方法
Java 9 提供了更简洁的不可变集合创建方式。
代码示例:
import java.util.List;
import java.util.Set;
import java.util.Map;
public class CollectionFactoryDemo {
public static void main(String[] args) {
// Java 9前
List<String> oldList = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList("a", "b", "c")));
// Java 9+
List<String> list = List.of("a", "b", "c");
Set<String> set = Set.of("a", "b", "c");
Map<String, Integer> map = Map.of("one", 1, "two", 2, "three", 3);
}
}
4. 钻石操作符支持匿名内部类
Java 9 允许在匿名内部类中使用钻石操作符。
代码示例:
// Java 9前
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
// Java 9+
Comparator<String> comparator = new Comparator<>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
5. try-with-resources 简化
Java 9 允许在 try-with-resources 中使用已声明的变量。
代码示例:
// Java 9前
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
// 读取文件
} catch (IOException e) {
e.printStackTrace();
}
// Java 9+
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
try (reader) { // 直接使用已声明的变量
// 读取文件
} catch (IOException e) {
e.printStackTrace();
}
三、Java 10(2018 年 3 月)—— 局部变量类型推断
1. 局部变量类型推断(var 关键字)
Java 10 引入了 var 关键字,允许编译器根据初始化表达式自动推断局部变量的类型。
代码示例:
public class VarDemo {
public static void main(String[] args) {
// 基本类型
var name = "Java 10"; // String
var age = 25; // int
// 复杂泛型
var complexMap = new HashMap<String, List<Integer>>(); // HashMap<String, List<Integer>>
// 循环中使用
for (var item : List.of(1, 2, 3)) {
System.out.println(item);
}
// try-with-resources中使用
try (var reader = new BufferedReader(new FileReader("file.txt"))) {
// 读取文件
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意事项:
-
var 只能用于局部变量(方法内、for 循环变量等)
-
变量必须初始化
-
不能用于成员变量、方法参数或返回值
-
不影响 Java 的强类型特性,编译后类型固定
2. 不可变集合增强
Java 10 为 Stream API 新增了 toUnmodifiableList ()、toUnmodifiableSet ()、toUnmodifiableMap () 方法。
代码示例:
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class UnmodifiableCollectionDemo {
public static void main(String[] args) {
var unmodifiableList = Stream.of("a", "b", "c")
.collect(Collectors.toUnmodifiableList());
// 以下操作会抛出UnsupportedOperationException
// unmodifiableList.add("d");
}
}
四、Java 11(2018 年 9 月,LTS)—— 简化与性能提升
1. Lambda 参数使用 var
Java 11 允许在 Lambda 参数中使用 var 关键字,支持添加注解。
代码示例:
// Java 11前
(x, y) -> x + y
// Java 11+,支持添加注解
(var x, @NonNull var y) -> x.process(y)
2. 字符串新增方法
Java 11 为 String 类新增了多个实用方法。
代码示例:
public class StringDemo {
public static void main(String[] args) {
String str = " Java 11 ";
// isBlank():检测空或空白字符
System.out.println(str.isBlank()); // false
System.out.println(" ".isBlank()); // true
// strip():去除首尾空白(支持Unicode)
System.out.println(str.strip()); // "Java 11"
// stripLeading():去除首部空白
System.out.println(str.stripLeading()); // "Java 11 "
// stripTrailing():去除尾部空白
System.out.println(str.stripTrailing()); // " Java 11"
// lines():拆分行为Stream
String multiLine = "Line 1\nLine 2\nLine 3";
multiLine.lines().forEach(System.out::println);
// repeat():重复字符串
System.out.println("Java ".repeat(3)); // "Java Java Java "
}
}
3. 标准化 HTTP 客户端
Java 11 正式标准化了 HTTP 客户端 API,支持 HTTP/2 和 WebSocket。
代码示例:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
public class HttpClientDemo {
public static void main(String[] args) throws Exception {
// 创建客户端
HttpClient client = HttpClient.newHttpClient();
// 同步请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com/users/openjdk"))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
// 异步请求
CompletableFuture<String> future = client.sendAsync(request,
HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body);
future.thenAccept(System.out::println);
}
}
4. 单文件源代码直接运行
Java 11 允许直接运行.java 文件,无需先编译。
命令示例:
# Java 11前
javac HelloWorld.java
java HelloWorld
# Java 11+
java HelloWorld.java
五、Java 12(2019 年 3 月)—— Switch 表达式预览
1. Switch 表达式(预览版)
Java 12 引入了 Switch 表达式的预览,支持箭头语法和返回值。
代码示例:
public class SwitchDemo {
public static void main(String[] args) {
String day = "MONDAY";
// 传统switch
String dayType;
switch (day) {
case "MONDAY":
case "TUESDAY":
case "WEDNESDAY":
case "THURSDAY":
case "FRIDAY":
dayType = "Weekday";
break;
case "SATURDAY":
case "SUNDAY":
dayType = "Weekend";
break;
default:
dayType = "Unknown";
}
// Java 12 Switch表达式
dayType = switch (day) {
case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> "Weekday";
case "SATURDAY", "SUNDAY" -> "Weekend";
default -> "Unknown";
};
System.out.println(dayType);
}
}
2. 字符串新增方法
Java 12 新增了 indent () 和 transform () 方法。
代码示例:
public class StringEnhanceDemo {
public static void main(String[] args) {
// indent():调整缩进
String text = "Hello\nJava\n12";
String indented = text.indent(4);
System.out.println(indented);
/* 输出:
Hello
Java
12
*/
// transform():链式处理字符串
String result = "foo"
.transform(s -> s + "bar")
.transform(String::toUpperCase);
System.out.println(result); // "FOOBAR"
}
}
六、Java 13(2019 年 9 月)—— 文本块与 Switch 改进
1. 文本块(预览版)
Java 13 引入了文本块,支持多行字符串,无需转义符。
代码示例:
public class TextBlockDemo {
public static void main(String[] args) {
// Java 13前
String json = "{\n" +
" \"name\": \"Java\",\n" +
" \"version\": 13\n" +
"}";
// Java 13文本块
String jsonBlock = """
{
"name": "Java",
"version": 13
}
""";
System.out.println(jsonBlock);
}
}
2. Switch 表达式改进(第二次预览)
Java 13 引入了 yield 关键字,用于在 switch 表达式的代码块中返回值。
代码示例:
public class SwitchYieldDemo {
public static void main(String[] args) {
String day = "MONDAY";
int hours = switch (day) {
case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY" -> {
System.out.println("Weekday");
yield 8; // 使用yield返回值
}
case "FRIDAY" -> {
System.out.println("Friday");
yield 7;
}
case "SATURDAY", "SUNDAY" -> {
System.out.println("Weekend");
yield 0;
}
default -> throw new IllegalArgumentException("Invalid day: " + day);
};
System.out.println("Working hours: " + hours);
}
}
七、Java 14(2020 年 3 月)—— Switch 正式版与 Records 预览
1. Switch 表达式正式版
Java 14 将 Switch 表达式正式转正。
代码示例:
public class SwitchExpressionDemo {
public static void main(String[] args) {
String day = "MONDAY";
// 直接返回值
String result = switch (day) {
case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> "工作日";
case "SATURDAY", "SUNDAY" -> "周末";
default -> throw new IllegalArgumentException("无效的日期: " + day);
};
System.out.println(result);
// 复杂逻辑使用yield
int workingHours = switch (day) {
case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY" -> {
System.out.println("工作日");
yield 8;
}
case "FRIDAY" -> {
System.out.println("周五");
yield 7;
}
case "SATURDAY", "SUNDAY" -> {
System.out.println("周末");
yield 0;
}
default -> throw new IllegalArgumentException("无效的日期: " + day);
};
System.out.println("工作时长: " + workingHours);
}
}
2. Records(预览版)
Records 是一种新的类类型,用于创建不可变的数据载体类,自动生成 equals ()、hashCode ()、toString () 等方法。
代码示例:
// 传统POJO
public class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + '}';
}
}
// 使用Records
public record UserRecord(String name, int age) {}
public class RecordDemo {
public static void main(String[] args) {
UserRecord user = new UserRecord("Alice", 30);
System.out.println(user.name()); // Alice
System.out.println(user.age()); // 30
System.out.println(user); // UserRecord[name=Alice, age=30]
UserRecord user2 = new UserRecord("Alice", 30);
System.out.println(user.equals(user2)); // true
}
}
3. instanceof 模式匹配(预览版)
Java 14 引入了 instanceof 模式匹配,允许在类型检查的同时直接转型并绑定变量。
代码示例:
public class InstanceOfDemo {
public static void main(String[] args) {
Object obj = "Hello Java 14";
// 传统方式
if (obj instanceof String) {
String str = (String) obj;
System.out.println(str.length());
}
// Java 14+ 模式匹配
if (obj instanceof String str) {
System.out.println(str.length());
}
// 结合条件
if (obj instanceof String str && str.length() > 5) {
System.out.println("长字符串: " + str);
}
}
}
八、Java 15(2020 年 9 月)—— 文本块正式版与 Sealed 类预览
1. 文本块正式版
Java 15 将文本块正式转正,并新增了两个转义符:
-
\:阻止插入换行符 -
\s:表示一个空格
代码示例:
public class TextBlockFinalDemo {
public static void main(String[] args) {
String html = """
<html>
<body>
<p>Hello, Java 15</p>
</body>
</html>
""";
System.out.println(html);
// 使用转义符
String text = """
Line 1\
Line 2
Line 3 with a space at the end \s
""";
System.out.println(text);
}
}
2. Sealed 类(预览版)
Sealed 类允许开发者精确控制哪些类可以继承或实现某个类或接口。
代码示例:
// 密封类
public sealed class Shape permits Circle, Rectangle, Triangle {
public abstract double area();
}
public final class Circle extends Shape {
private final double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
public final class Rectangle extends Shape {
private final double width;
private final double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double area() {
return width * height;
}
}
public final class Triangle extends Shape {
private final double base;
private final double height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
@Override
public double area() {
return 0.5 * base * height;
}
}
九、Java 16(2021 年 3 月)—— Records 与模式匹配正式版
1. Records 正式版
Java 16 将 Records 正式转正,成为 Java 的正式特性。
代码示例:
// 定义记录类
public record Person(String name, int age, String email) {
// 可以添加自定义方法
public String fullInfo() {
return name + " (" + age + "): " + email;
}
// 可以添加紧凑构造器
public Person {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数: " + age);
}
}
}
public class RecordFinalDemo {
public static void main(String[] args) {
Person person = new Person("Bob", 25, "bob@example.com");
System.out.println(person.fullInfo()); // Bob (25): bob@example.com
// 解构记录
String name = person.name();
int age = person.age();
System.out.println(name + " is " + age + " years old");
}
}
2. instanceof 模式匹配正式版
Java 16 将 instanceof 模式匹配正式转正。
代码示例:
public class InstanceOfFinalDemo {
public static void main(String[] args) {
Object obj = new Person("Alice", 30, "alice@example.com");
// 模式匹配结合记录
if (obj instanceof Person p) {
System.out.println("姓名: " + p.name());
System.out.println("年龄: " + p.age());
}
// 嵌套模式匹配
Object data = new ArrayList<>(List.of(new Person("Bob", 25, "bob@example.com")));
if (data instanceof List<?> list && !list.isEmpty() && list.get(0) instanceof Person p) {
System.out.println("列表中的第一个人: " + p.name());
}
}
}
3. Sealed 类第二次预览
Java 16 对 Sealed 类进行了改进,增加了更严格的引用检查。
十、Java 17(2021 年 9 月,LTS)—— Sealed 类正式版与 UTF-8 默认编码
1. Sealed 类正式版
Java 17 将 Sealed 类正式转正。
代码示例:
// 密封接口
public sealed interface Result permits Success, Failure, Retry {
}
public record Success(Object data) implements Result {
}
public record Failure(String errorMessage) implements Result {
}
public record Retry(int remainingAttempts) implements Result {
}
public class SealedFinalDemo {
public static void handleResult(Result result) {
String message = switch (result) {
case Success s -> "成功: " + s.data();
case Failure f -> "失败: " + f.errorMessage();
case Retry r -> "重试,剩余次数: " + r.remainingAttempts();
};
System.out.println(message);
}
}
2. UTF-8 默认编码
Java 17 将 UTF-8 设为默认字符编码,解决了跨平台编码不一致的问题。
代码示例:
// Java 17前,不同平台默认编码可能不同
// Java 17+,默认使用UTF-8
try (FileReader reader = new FileReader("file.txt");
FileWriter writer = new FileWriter("output.txt")) {
// 读写文件默认使用UTF-8
} catch (IOException e) {
e.printStackTrace();
}
3. Switch 模式匹配(预览版)
Java 17 引入了 Switch 模式匹配的预览,允许在 switch 中使用类型模式。
代码示例:
public class SwitchPatternDemo {
public static String formatObject(Object obj) {
return switch (obj) {
case Integer i -> "整数: " + i;
case String s -> "字符串: " + s;
case Double d -> "浮点数: " + d;
case Person p -> "人员: " + p.name() + ", " + p.age();
case null -> "空值";
default -> "未知类型: " + obj.getClass().getName();
};
}
public static void main(String[] args) {
System.out.println(formatObject(42)); // 整数: 42
System.out.println(formatObject("Hello")); // 字符串: Hello
System.out.println(formatObject(new Person("Alice", 30, "alice@example.com"))); // 人员: Alice, 30
}
}
十一、Java 18(2022 年 3 月)—— UTF-8 正式与简单 Web 服务器
1. UTF-8 默认编码正式版
Java 18 将 UTF-8 默认编码正式转正,确保所有 Java API 默认使用 UTF-8。
2. 简单 Web 服务器(jwebserver)
Java 18 引入了简单的 Web 服务器工具,用于快速启动静态文件服务器。
命令示例:
# 启动Web服务器,默认端口8000
jwebserver
# 指定端口
jwebserver -p 8080
# 指定目录
jwebserver -d /path/to/directory
3. Javadoc 代码片段(@snippet 标签)
Java 18 增强了 Javadoc,支持 @snippet 标签嵌入代码示例。
代码示例:
/**
* 这是一个示例类
* {@snippet lang="java" :
* public class Example {
* public static void main(String[] args) {
* System.out.println("Hello Java 18");
* }
* }
* }
*/
public class JavadocSnippetDemo {
}
十二、Java 19(2022 年 9 月)—— 虚拟线程与 Record 模式
1. 虚拟线程(预览版)
Java 19 引入了虚拟线程(Project Loom 的核心特性),是轻量级的线程,由 JVM 管理,支持百万级并发。
代码示例:
public class VirtualThreadDemo {
public static void main(String[] args) throws InterruptedException {
// 创建虚拟线程
Thread virtualThread = Thread.ofVirtual().start(() -> {
System.out.println("虚拟线程运行中");
try {
Thread.sleep(1000); // 模拟IO操作
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("虚拟线程完成");
});
virtualThread.join();
// 批量创建虚拟线程
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10_000; i++) {
executor.submit(() -> {
Thread.sleep(1000);
System.out.println("任务 " + i + " 完成");
return i;
});
}
} // 自动关闭executor
}
}
2. Record 模式(预览版)
Java 19 引入了 Record 模式,允许解构记录类型。
代码示例:
public record Point(int x, int y) {}
public record Circle(Point center, double radius) {}
public record Rectangle(Point topLeft, Point bottomRight) {}
public class RecordPatternDemo {
public static void printShape(Object shape) {
String result = switch (shape) {
case Circle(Point(int x, int y), double r) ->
"圆心: (" + x + ", " + y + "), 半径: " + r;
case Rectangle(Point(int x1, int y1), Point(int x2, int y2)) ->
"左上角: (" + x1 + ", " + y1 + "), 右下角: (" + x2 + ", " + y2 + ")";
default -> "未知形状";
};
System.out.println(result);
}
public static void main(String[] args) {
Circle circle = new Circle(new Point(10, 20), 5.0);
Rectangle rectangle = new Rectangle(new Point(0, 0), new Point(100, 200));
printShape(circle); // 圆心: (10, 20), 半径: 5.0
printShape(rectangle); // 左上角: (0, 0), 右下角: (100, 200)
}
}
十三、Java 20(2023 年 3 月)—— 模式匹配与虚拟线程改进
1. Record 模式第二次预览
Java 20 对 Record 模式进行了改进,支持更复杂的嵌套模式。
代码示例:
public record Address(String street, String city, String zipCode) {}
public record Person(String name, int age, Address address) {}
public class NestedRecordPatternDemo {
public static void printPersonInfo(Object obj) {
if (obj instanceof Person(String name, int age, Address(String street, String city, String zip))) {
System.out.println("姓名: " + name);
System.out.println("年龄: " + age);
System.out.println("地址: " + street + ", " + city + " " + zip);
}
}
public static void main(String[] args) {
Person person = new Person("Alice", 30, new Address("Main St", "New York", "10001"));
printPersonInfo(person);
}
}
2. Switch 模式匹配第四次预览
Java 20 继续完善 Switch 模式匹配,支持 when 子句。
代码示例:
public class SwitchWhenDemo {
public static String formatNumber(Object obj) {
return switch (obj) {
case Integer i when i > 0 -> "正整数: " + i;
case Integer i when i < 0 -> "负整数: " + i;
case Integer i -> "零";
case Double d when d > 0 -> "正浮点数: " + d;
case Double d when d < 0 -> "负浮点数: " + d;
case Double d -> "零";
default -> "不是数字";
};
}
public static void main(String[] args) {
System.out.println(formatNumber(42)); // 正整数: 42
System.out.println(formatNumber(-3.14)); // 负浮点数: -3.14
System.out.println(formatNumber(0)); // 零
}
}
十四、Java 21(2023 年 9 月,LTS)—— 虚拟线程与模式匹配正式版
1. 虚拟线程正式版
Java 21 将虚拟线程正式转正,成为 Java 的核心并发特性。
代码示例:
public class VirtualThreadFinalDemo {
public static void main(String[] args) throws InterruptedException {
// 方式1:创建虚拟线程
Thread virtualThread = Thread.ofVirtual().name("my-virtual-thread").start(() -> {
System.out.println("虚拟线程 " + Thread.currentThread().getName() + " 运行中");
try {
// 模拟IO操作
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("虚拟线程 " + Thread.currentThread().getName() + " 完成");
});
virtualThread.join();
// 方式2:使用ExecutorService
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
// 提交1000个虚拟线程任务
for (int i = 0; i < 1000; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("任务 " + taskId + " 开始");
Thread.sleep(100); // 模拟IO操作
System.out.println("任务 " + taskId + " 完成");
return taskId;
});
}
} // 自动关闭executor,等待所有任务完成
}
}
2. Record 模式正式版
Java 21 将 Record 模式正式转正,支持嵌套模式和模式匹配的完整功能。
代码示例:
public record Author(String name, int birthYear) {}
public record Book(String title, Author author, int publicationYear) {}
public class RecordPatternFinalDemo {
public static void printBookInfo(Object obj) {
String info = switch (obj) {
case Book(String title, Author(String authorName, int authorBirthYear), int pubYear) ->
"《" + title + "》作者: " + authorName + " (" + authorBirthYear + "), 出版年份: " + pubYear;
case Book(String title, null, int pubYear) ->
"《" + title + "》作者未知, 出版年份: " + pubYear;
default -> "不是书籍对象";
};
System.out.println(info);
}
public static void main(String[] args) {
Author author = new Author("George Orwell", 1903);
Book book = new Book("1984", author, 1949);
printBookInfo(book); // 《1984》作者: George Orwell (1903), 出版年份: 1949
}
}
3. Switch 模式匹配正式版
Java 21 将 Switch 模式匹配正式转正,支持完整的模式匹配功能。
代码示例:
public class SwitchPatternFinalDemo {
public static String processObject(Object obj) {
return switch (obj) {
case null -> "空值";
case String s -> "字符串: '" + s + "',长度: " + s.length();
case Integer i -> "整数: " + i;
case Double d -> "浮点数: " + d;
case List<?> list when list.isEmpty() -> "空列表";
case List<?> list -> "列表,大小: " + list.size();
case Book b -> "书籍: " + b.title();
default -> "未知类型: " + obj.getClass().getSimpleName();
};
}
public static void main(String[] args) {
System.out.println(processObject("Hello Java 21")); // 字符串: 'Hello Java 21',长度: 13
System.out.println(processObject(42)); // 整数: 42
System.out.println(processObject(List.of(1, 2, 3))); // 列表,大小: 3
}
}
4. 序列化集合(Sequenced Collections)
Java 21 引入了 Sequenced Collections,提供了统一的有序集合操作接口。
代码示例:
import java.util.SequencedCollection;
import java.util.SequencedSet;
import java.util.SequencedMap;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
public class SequencedCollectionsDemo {
public static void main(String[] args) {
// SequencedCollection
SequencedCollection<String> list = new ArrayList<>();
list.addFirst("First");
list.addLast("Last");
System.out.println(list.getFirst()); // First
System.out.println(list.getLast()); // Last
SequencedCollection<String> reversed = list.reversed();
System.out.println(reversed); // [Last, First]
// SequencedSet
SequencedSet<String> set = new LinkedHashSet<>();
set.add("A");
set.add("B");
set.add("C");
System.out.println(set.getFirst()); // A
System.out.println(set.getLast()); // C
// SequencedMap
SequencedMap<String, Integer> map = new LinkedHashMap<>();
map.put("One", 1);
map.put("Two", 2);
map.put("Three", 3);
System.out.println(map.firstEntry()); // One=1
System.out.println(map.lastEntry()); // Three=3
SequencedMap<String, Integer> reversedMap = map.reversed();
System.out.println(reversedMap); // {Three=3, Two=2, One=1}
}
}
5. 字符串模板(预览版)
Java 21 引入了字符串模板的预览,提供了更安全、更灵活的字符串插值方式。
代码示例:
import static java.lang.StringTemplate.STR;
public class StringTemplateDemo {
public static void main(String[] args) {
String name = "Alice";
int age = 30;
// 传统字符串拼接
String oldWay = "姓名: " + name + ", 年龄: " + (age + 1);
// 字符串模板
String newWay = STR."姓名: \{name}, 年龄: \{age + 1}";
System.out.println(newWay); // 姓名: Alice, 年龄: 31
// 多行模板
String multiLine = STR."""
姓名: \{name}
年龄: \{age}
明年年龄: \{age + 1}
""";
System.out.println(multiLine);
}
}
十五、Java 22(2024 年 3 月)—— 未命名变量与灵活构造函数
1. 未命名变量和模式正式版
Java 22 将未命名变量和模式正式转正,允许使用下划线_表示不需要的变量。
代码示例:
public class UnnamedVariablesDemo {
public static void main(String[] args) {
// 忽略异常
try {
// 可能抛出异常的代码
Integer.parseInt("not a number");
} catch (NumberFormatException _) { // 忽略异常变量
System.out.println("数字格式错误");
}
// 忽略不需要的返回值
record Person(String name, int age, String email) {}
Person person = new Person("Bob", 25, "bob@example.com");
// 只关心姓名,忽略年龄和邮箱
var (name, _, _) = person;
System.out.println("姓名: " + name);
// switch中忽略不需要的模式
Object obj = 42;
String result = switch (obj) {
case Integer _ -> "这是一个整数";
case String _ -> "这是一个字符串";
default -> "未知类型";
};
System.out.println(result);
}
}
2. 灵活构造函数体(预览版)
Java 22 允许在构造函数中,在调用 super () 或 this () 之前执行语句。
代码示例:
public class Parent {
private final String name;
public Parent(String name) {
this.name = name;
System.out.println("父类构造函数: " + name);
}
}
public class Child extends Parent {
private final int age;
public Child(String name, int age) {
// Java 22前,super()必须是第一条语句
// super(name);
// Java 22+,可以在super()前执行语句
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数: " + age);
}
String validatedName = name != null ? name.trim() : "Unknown";
super(validatedName);
this.age = age;
System.out.println("子类构造函数: " + age);
}
}
3. 模块导入声明(预览版)
Java 22 引入了模块导入声明,允许批量导入模块导出的所有包。
代码示例:
// 导入整个模块的所有包
import module java.util;
import module java.io;
public class ModuleImportDemo {
public static void main(String[] args) {
// 可以直接使用模块中的类,无需单独导入
List<String> list = new ArrayList<>();
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
}
}
十六、Java 23(2024 年 9 月)—— 基本类型模式匹配与隐式类
1. 基本类型模式匹配(预览版)
Java 23 扩展了模式匹配,支持基本类型(int、double、boolean 等)。
代码示例:
public class PrimitivePatternDemo {
public static String processPrimitive(Object obj) {
return switch (obj) {
case int i -> "整数: " + i;
case long l -> "长整数: " + l;
case double d -> "浮点数: " + d;
case boolean b -> "布尔值: " + b;
case char c -> "字符: '" + c + "'";
default -> "不是基本类型";
};
}
public static void main(String[] args) {
System.out.println(processPrimitive(42)); // 整数: 42
System.out.println(processPrimitive(3.14)); // 浮点数: 3.14
System.out.println(processPrimitive(true)); // 布尔值: true
}
}
2. 隐式类与实例 main 方法(预览版)
Java 23 允许省略显式类声明,简化入门代码和脚本开发。
代码示例:
// 隐式类,无需声明class
void main() {
System.out.println("Hello Java 23");
}
// 支持命令行参数
void main(String[] args) {
System.out.println("参数数量: " + args.length);
for (String arg : args) {
System.out.println("参数: " + arg);
}
}
3. Markdown 文档注释
Java 23 支持在 Javadoc 中使用 Markdown 语法,提升文档可读性。
代码示例:
/**
* # 示例类
*
* 这是一个使用Markdown文档注释的示例类。
*
* ## 功能特性
* - 支持Markdown语法
* - 更易读的文档
* - 支持列表、标题、链接等
*
* ## 使用示例
* ```java
* Example example = new Example();
* example.doSomething();
* ```
*
* @see <a href="https://openjdk.org">OpenJDK</a>
*/
public class MarkdownJavadocDemo {
/**
* 执行某个操作
*
* @param param 参数描述
* @return 返回值描述
*/
public String doSomething(String param) {
return "处理: " + param;
}
}
十七、Java 24(2025 年 3 月)—— 模式匹配与模块导入改进
1. 基本类型模式匹配第二次预览
Java 24 对基本类型模式匹配进行了改进,支持更复杂的模式。
代码示例:
public class PrimitivePatternEnhanceDemo {
public static String processNumber(Object obj) {
return switch (obj) {
case int i when i > 0 -> "正整数: " + i;
case int i when i < 0 -> "负整数: " + i;
case int i -> "零";
case double d when d > 0 -> "正浮点数: " + d;
case double d when d < 0 -> "负浮点数: " + d;
case double d -> "零";
default -> "不是数字";
};
}
public static void main(String[] args) {
System.out.println(processNumber(42)); // 正整数: 42
System.out.println(processNumber(-3.14)); // 负浮点数: -3.14
System.out.println(processNumber(0)); // 零
}
}
2. 模块导入声明第二次预览
Java 24 改进了模块导入声明,支持更灵活的导入方式。
代码示例:
// 导入整个模块
import module java.base;
// 导入模块的特定包
import module java.util {
import java.util.List;
import java.util.Map;
}
public class ModuleImportEnhanceDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();
}
}
十八、Java 25(2025 年 9 月,LTS)—— 简洁语法与并发改进
1. 紧凑源文件与实例 main 方法正式版
Java 25 将紧凑源文件与实例 main 方法正式转正,允许编写更简洁的 Java 程序。
代码示例:
// 最简单的Java程序,无需类声明
void main() {
System.out.println("Hello Java 25");
}
// 支持命令行参数
void main(String[] args) {
System.out.println("Hello, " + (args.length > 0 ? args[0] : "World"));
}
// 可以包含多个方法
void main() {
String message = getMessage();
System.out.println(message);
}
String getMessage() {
return "Hello from Java 25";
}
2. 灵活构造函数体正式版
Java 25 将灵活构造函数体正式转正,允许在构造函数中更灵活地组织代码。
代码示例:
public class Product {
private final String id;
private final String name;
private final double price;
public Product(String id, String name, double price) {
// 参数校验
if (id == null || id.isBlank()) {
throw new IllegalArgumentException("ID不能为空");
}
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("名称不能为空");
}
if (price <= 0) {
throw new IllegalArgumentException("价格必须大于0");
}
// 预处理
String normalizedId = id.trim().toUpperCase();
String normalizedName = name.trim();
// 调用父类构造函数(如果有)
super();
this.id = normalizedId;
this.name = normalizedName;
this.price = price;
}
}
3. 模块导入声明正式版
Java 25 将模块导入声明正式转正,简化模块化代码的编写。
代码示例:
// 导入整个模块
import module java.util;
import module java.io;
import module com.example.utils;
public class ModuleImportFinalDemo {
public static void main(String[] args) {
// 可以直接使用所有导入模块中的类
List<String> list = new ArrayList<>();
BufferedReader reader = new BufferedReader(new FileReader("data.txt"));
StringUtils utils = new StringUtils();
}
}
4. 字符串模板正式版
Java 25 将字符串模板正式转正,提供了安全、高效的字符串插值方式。
代码示例:
import static java.lang.StringTemplate.STR;
import static java.lang.StringTemplate.FMT;
public class StringTemplateFinalDemo {
public static void main(String[] args) {
String name = "Alice";
int age = 30;
double height = 1.75;
// 基础模板
String info = STR."姓名: \{name}, 年龄: \{age}";
System.out.println(info);
// 格式化模板
String formatted = FMT."姓名: %s, 年龄: %d, 身高: %.2f米" \{name, age, height};
System.out.println(formatted);
// 多行模板
String profile = STR."""
个人档案
--------
姓名: \{name}
年龄: \{age}
身高: \{height}米
明年年龄: \{age + 1}
""";
System.out.println(profile);
}
}
5. 基本类型模式匹配第三次预览
Java 25 继续完善基本类型模式匹配,支持更复杂的场景。
代码示例:
public class PrimitivePatternFinalDemo {
public static void processValue(Object obj) {
switch (obj) {
case int i -> System.out.printf("整数: %d%n", i);
case long l -> System.out.printf("长整数: %d%n", l);
case double d -> System.out.printf("浮点数: %.2f%n", d);
case boolean b -> System.out.printf("布尔值: %b%n", b);
case char c -> System.out.printf("字符: %c%n", c);
// 支持包装类型
case Integer i -> System.out.printf("整数包装类型: %d%n", i);
case Double d -> System.out.printf("浮点数包装类型: %.2f%n", d);
default -> System.out.println("未知类型");
}
}
public static void main(String[] args) {
processValue(42);
processValue(3.14159);
processValue('A');
processValue(true);
processValue(Integer.valueOf(100));
}
}
总结
从 Java 8 到 Java 25,Java 语言经历了重大的演进,主要体现在以下几个方面:
-
函数式编程:Java 8 引入的 Lambda 表达式和 Stream API 彻底改变了 Java 的编程风格,使代码更简洁、更具表达力。
-
简化代码:从 var 关键字、Records、文本块到紧凑源文件,Java 不断减少样板代码,提高开发效率。
-
模式匹配:从 instanceof 模式匹配到 Switch 模式匹配,再到基本类型模式匹配,Java 的类型处理越来越灵活和安全。
-
并发编程:虚拟线程、结构化并发和作用域值的引入,使 Java 的并发编程变得更简单、更高效。
-
模块化:Java 9 引入的模块系统,解决了大型项目的依赖管理问题,提高了代码的安全性和可维护性。
-
开发体验:UTF-8 默认编码、友好的空指针异常、Markdown 文档注释等改进,提升了开发者的使用体验。
Java 的演进始终围绕着提高开发效率、增强语言表达力、提升性能和安全性的目标,使 Java 在保持稳定性的同时,不断适应现代软件开发的需求。
(注:文档部分内容可能由 AI 生成)