Java语法更新

Java语法更新

本文内容由 AI 辅助生成,已经人工审核和编辑。

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 语言经历了重大的演进,主要体现在以下几个方面:

  1. 函数式编程:Java 8 引入的 Lambda 表达式和 Stream API 彻底改变了 Java 的编程风格,使代码更简洁、更具表达力。

  2. 简化代码:从 var 关键字、Records、文本块到紧凑源文件,Java 不断减少样板代码,提高开发效率。

  3. 模式匹配:从 instanceof 模式匹配到 Switch 模式匹配,再到基本类型模式匹配,Java 的类型处理越来越灵活和安全。

  4. 并发编程:虚拟线程、结构化并发和作用域值的引入,使 Java 的并发编程变得更简单、更高效。

  5. 模块化:Java 9 引入的模块系统,解决了大型项目的依赖管理问题,提高了代码的安全性和可维护性。

  6. 开发体验:UTF-8 默认编码、友好的空指针异常、Markdown 文档注释等改进,提升了开发者的使用体验。

Java 的演进始终围绕着提高开发效率、增强语言表达力、提升性能和安全性的目标,使 Java 在保持稳定性的同时,不断适应现代软件开发的需求。

(注:文档部分内容可能由 AI 生成)

网络编程套接字 2026-02-05

评论区