目录
正在加载目录…
专栏文章
专栏文章
Java 专栏
1. Java:跨平台语言与生态全景 2. Java 并发:JMM、锁与线程池原理 3. JVM:类加载、内存、GC 与性能诊断 4. Java 性能调优:CPU、内存、锁与 IO 排查 5. Java 新特性速查:从 Lambda 到虚拟线程 6. Java 业务开发:高频陷阱与 Code Review 清单 7. Java 核心知识:集合、并发与 JVM 面试要点 8. AQS 原理:同步队列与加锁解锁全流程 9. JVM 与 Linux 内存:分区、分配与 GC 边界 10. AtomicLong 与 LongAdder:并发计数器选型 11. Java 引用与内存泄漏:六类场景与修复 12. Java 测试实践:JUnit、Mockito 与 Testcontainers 13. Java 并发入门:线程、锁与线程池全景

Java 新特性速查:从 Lambda 到虚拟线程

发布于 2026-06-17 14:40 · 最后编辑于 2026-07-31 15:51 · 字数 1,940 👁 170 次阅读

本文覆盖 Java 8 到 Java 21 的核心新特性,包含 Lambda/Stream/Optional/CompletableFuture/模块化/Record/Sealed/文字块/虚拟线程,每个特性附有代码示例和适用场景说明,供快速查阅。

目录

章节Java 版本说明
Java 8 核心特性8Lambda、Stream、Optional、新时间 API
Java 9-11 特性9-11模块化、集合工厂方法、var、HTTP Client
Java 12-16 特性12-16Switch 表达式、文字块、Record、instanceof 增强
Java 17 特性17 LTSSealed Class 正式版
Java 21 特性21 LTS虚拟线程、Switch 模式匹配、Sequenced Collections
版本特性速查表一表总览

Java 8 核心特性

Lambda 表达式

// 函数式接口:只有一个抽象方法的接口,可用 Lambda 实现
@FunctionalInterface
interface Greeter {
    String greet(String name);
}

// Lambda 写法
Greeter g = name -> "Hello, " + name + "!";
System.out.println(g.greet("Alice"));   // Hello, Alice!

// 方法引用(Lambda 的简化写法)
List<String> names = List.of("Bob", "Alice", "Charlie");
names.stream()
     .sorted(String::compareToIgnoreCase)  // 方法引用
     .forEach(System.out::println);         // 实例方法引用

常用函数式接口

接口签名说明
Runnable() -> void无参无返回
Supplier<T>() -> T无参有返回
Consumer<T>T -> void有参无返回
Function<T, R>T -> R有参有返回
Predicate<T>T -> boolean断言
BiFunction<T, U, R>(T, U) -> R双参有返回

Stream API

import java.util.stream.*;

List<String> words = List.of("banana", "apple", "cherry", "avocado");

// 过滤 → 映射 → 排序 → 收集
List<String> result = words.stream()
    .filter(w -> w.startsWith("a"))          // 过滤
    .map(String::toUpperCase)                 // 映射
    .sorted()                                 // 排序
    .collect(Collectors.toList());
// [APPLE, AVOCADO]

// 统计操作
long count = words.stream().filter(w -> w.length() > 5).count();
Optional<String> longest = words.stream()
    .max(Comparator.comparingInt(String::length));

// 数值流(避免装箱)
int[] nums = {1, 2, 3, 4, 5};
int sum = IntStream.of(nums).sum();
double avg = IntStream.of(nums).average().orElse(0);

// 分组
Map<Integer, List<String>> byLength = words.stream()
    .collect(Collectors.groupingBy(String::length));

// 分区(按 boolean)
Map<Boolean, List<String>> partitioned = words.stream()
    .collect(Collectors.partitioningBy(w -> w.length() > 5));

// 字符串拼接
String joined = words.stream()
    .collect(Collectors.joining(", ", "[", "]"));
// [banana, apple, cherry, avocado]

// flatMap:将多层结构展平
List<List<Integer>> nested = List.of(List.of(1, 2), List.of(3, 4));
List<Integer> flat = nested.stream()
    .flatMap(Collection::stream)
    .collect(Collectors.toList());
// [1, 2, 3, 4]

// 并行流(CPU 密集型大数据集)
long parallelSum = LongStream.rangeClosed(1, 1_000_000)
    .parallel()
    .sum();

Stream 惰性求值:中间操作(filter/map/sorted)不立即执行,终止操作(collect/count/forEach)触发整个管道执行。

Optional

import java.util.Optional;

// 避免 NullPointerException 的容器类
Optional<String> opt = Optional.ofNullable(getValue());  // 可能为 null

// 获取值
String val = opt.orElse("default");           // 有值取值,否则返回默认
String val2 = opt.orElseGet(() -> compute()); // 懒加载默认值
String val3 = opt.orElseThrow(IllegalStateException::new);

// 链式操作
Optional<Integer> len = opt
    .filter(s -> s.length() > 3)
    .map(String::length);

// 存在时执行
opt.ifPresent(s -> System.out.println(s.toUpperCase()));

// Java 9+:ifPresentOrElse
opt.ifPresentOrElse(
    s -> System.out.println("Found: " + s),
    () -> System.out.println("Not found")
);

// Java 9+:or(返回另一个 Optional)
Optional<String> fallback = opt.or(() -> Optional.of("fallback"));

新时间 API(java.time)

import java.time.*;
import java.time.format.*;

// 本地日期时间(无时区)
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.of(14, 30, 0);
LocalDateTime dt = LocalDateTime.now();

// 带时区
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));

// 格式化
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String str = dt.format(fmt);
LocalDateTime parsed = LocalDateTime.parse("2024-01-15 10:30:00", fmt);

// 日期计算
LocalDate tomorrow = date.plusDays(1);
LocalDate lastMonth = date.minusMonths(1);
long daysBetween = ChronoUnit.DAYS.between(date, tomorrow);

// 时间段
Duration duration = Duration.between(time, LocalTime.now());
Period period = Period.between(date, LocalDate.of(2025, 1, 1));

Java 9-11 特性

模块化系统(Java 9)

// module-info.java(放在 src/ 根目录)
module com.example.myapp {
    requires java.base;          // 隐式依赖,可省略
    requires java.sql;           // 声明依赖的模块
    requires transitive java.logging;  // 传递依赖

    exports com.example.api;     // 对外暴露的包
    exports com.example.util to com.example.client;  // 限定导出

    opens com.example.model;     // 允许反射访问(运行时)
}

模块化主要用于构建大型应用和 JDK 本身的精简化,普通 Spring Boot 项目通常不需要手动编写 module-info.java

集合工厂方法(Java 9)

// 不可变集合(不支持 null 元素)
List<String> list = List.of("a", "b", "c");
Set<Integer> set = Set.of(1, 2, 3);
Map<String, Integer> map = Map.of("one", 1, "two", 2);
Map<String, Integer> map2 = Map.ofEntries(
    Map.entry("one", 1),
    Map.entry("two", 2)
);

// 可变集合的不可变视图
List<String> unmodifiable = Collections.unmodifiableList(new ArrayList<>());

var 局部变量类型推断(Java 10)

// var 只能用于局部变量,编译期推断类型
var name = "Alice";                          // String
var list = new ArrayList<String>();          // ArrayList<String>
var map = new HashMap<String, Integer>();    // HashMap<String, Integer>

// 在 for-each 中使用
for (var entry : map.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

// 不能用于:字段、方法参数、返回值、Lambda 参数

HTTP Client(Java 11)

import java.net.http.*;
import java.net.URI;

HttpClient client = HttpClient.newHttpClient();

// 同步请求
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/data"))
    .header("Content-Type", "application/json")
    .GET()
    .build();

HttpResponse<String> response = client.send(request,
    HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());  // 200
System.out.println(response.body());

// 异步请求
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println);

Java 12-16 特性

Switch 表达式(Java 14 正式)

// 旧写法:switch 语句(容易遗漏 break)
String grade;
switch (score / 10) {
    case 10: case 9: grade = "A"; break;
    case 8:          grade = "B"; break;
    default:         grade = "F";
}

// 新写法:switch 表达式(箭头语法,无 fall-through)
String grade = switch (score / 10) {
    case 10, 9 -> "A";
    case 8     -> "B";
    case 7     -> "C";
    default    -> "F";
};

// yield:在代码块中返回值
String result = switch (day) {
    case MONDAY, FRIDAY -> "工作日";
    case SATURDAY, SUNDAY -> {
        System.out.println("周末");
        yield "休息日";   // 代码块中用 yield 返回
    }
    default -> "其他";
};

文字块 Text Block(Java 15 正式)

// 旧写法:多行字符串需要大量转义和拼接
String json = "{\"name\": \"Alice\", \"age\": 30}";

// 文字块:所见即所得,开始分隔符必须单独成行
String json = """
        {
            "name": "Alice",
            "age": 30
        }
        """;

// 文字块就是字符串,可以调用所有 String 方法
String html = """
        <html>
            <body>
                <h1>%s</h1>
            </body>
        </html>
        """.formatted("Hello World!");

// 编译期处理:
// 1. 换行符统一为 LF
// 2. 删除共享前导空格(结束分隔符的位置决定缩进量)
// 3. 处理转义字符(\s 保留尾部空格,\ 行末取消换行)

Record 档案类(Java 16 正式)

// Record:不可变数据载体,自动生成构造器、getter、equals、hashCode、toString
public record Point(double x, double y) {
    // 紧凑构造器(用于参数校验)
    public Point {
        if (x < 0 || y < 0) throw new IllegalArgumentException("坐标不能为负");
    }

    // 可以添加自定义方法
    public double distance() {
        return Math.sqrt(x * x + y * y);
    }

    // 可以实现接口
}

// 使用
Point p = new Point(3.0, 4.0);
System.out.println(p);          // Point[x=3.0, y=4.0]
System.out.println(p.x());      // 3.0(getter 无 get 前缀)
System.out.println(p.distance()); // 5.0
System.out.println(p.equals(new Point(3.0, 4.0)));  // true

// Record 不可继承,但可以实现接口
public record Circle(double radius) implements Shape {
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

Record vs POJO:Record 天然不可变,适合 DTO、值对象、数据载体;POJO 可变,适合需要修改字段的业务对象。

instanceof 模式匹配(Java 16 正式)

// 旧写法:类型判断 + 强制转换
if (obj instanceof String) {
    String s = (String) obj;   // 多余的转换
    System.out.println(s.length());
}

// 新写法:instanceof 模式匹配,自动绑定变量
if (obj instanceof String s) {
    System.out.println(s.length());  // s 直接可用
}

// 结合 &&
if (obj instanceof String s && s.length() > 5) {
    System.out.println("长字符串: " + s);
}

Java 17 特性

Sealed Class 封闭类(Java 17 正式)

// 封闭类:限制可以继承它的子类,实现"可穷举的类型层次"
public sealed interface Shape
    permits Circle, Rectangle, Triangle {}

// 许可类必须声明自身的扩展性
public record Circle(double radius) implements Shape {}          // final(record 默认)
public record Rectangle(double width, double height) implements Shape {}
public non-sealed class Triangle implements Shape {              // 解封,允许任意继承
    // ...
}

// 封闭类的价值:配合 switch 模式匹配,编译器可检查穷举性
static double area(Shape shape) {
    return switch (shape) {
        case Circle c    -> Math.PI * c.radius() * c.radius();
        case Rectangle r -> r.width() * r.height();
        case Triangle t  -> /* ... */ 0;
        // 无需 default:编译器知道所有子类
    };
}

封闭类的扩展性控制

许可类声明含义
final彻底关闭扩展
sealed继续受限扩展(需再声明 permits)
non-sealed解封,允许任意继承

Java 21 特性

虚拟线程 Virtual Thread(Java 21 正式)

// 虚拟线程:JVM 管理的轻量级线程,可创建百万级,适合 IO 密集型任务
// 底层映射到少量平台线程(OS 线程),IO 阻塞时自动让出平台线程

// 方式一:直接创建
Thread vt = Thread.ofVirtual().start(() ->
    System.out.println("Running in: " + Thread.currentThread())
);
vt.join();

// 方式二:使用虚拟线程执行器(推荐)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    for (int i = 0; i < 100_000; i++) {
        final int id = i;
        executor.submit(() -> {
            // 模拟 IO 阻塞(不会占用平台线程)
            Thread.sleep(Duration.ofMillis(100));
            return "task " + id;
        });
    }
}   // try-with-resources 自动 shutdown

// 方式三:命名虚拟线程(便于调试)
Thread.ofVirtual()
    .name("worker-", 0)   // 生成 worker-0, worker-1, ...
    .start(runnable);

虚拟线程 vs 平台线程

维度平台线程虚拟线程
创建成本高(MB 级栈,OS 调度)极低(KB 级,JVM 调度)
数量上限数千数百万
适用场景CPU 密集型IO 密集型(HTTP/DB/文件)
阻塞行为占用 OS 线程自动让出平台线程

注意:虚拟线程不适合 CPU 密集型任务,也不适合使用 synchronized 持有锁时阻塞(会 pin 住平台线程),应改用 ReentrantLock

Switch 模式匹配(Java 21 正式)

// switch 支持任意类型的模式匹配
static String describe(Object obj) {
    return switch (obj) {
        case Integer i when i > 0 -> "正整数: " + i;    // when 守卫
        case Integer i            -> "非正整数: " + i;
        case String s             -> "字符串,长度: " + s.length();
        case null                 -> "null";             // 显式处理 null
        default                   -> "其他类型: " + obj.getClass().getSimpleName();
    };
}

// 配合 Sealed Class,无需 default
sealed interface Shape permits Circle, Rectangle {}
record Circle(double r) implements Shape {}
record Rectangle(double w, double h) implements Shape {}

static double area(Shape s) {
    return switch (s) {
        case Circle c    -> Math.PI * c.r() * c.r();
        case Rectangle r -> r.w() * r.h();
        // 编译器验证穷举性,无需 default
    };
}

Sequenced Collections(Java 21)

// 新接口:SequencedCollection / SequencedSet / SequencedMap
// 统一了"有序集合的首尾操作"

List<String> list = new ArrayList<>(List.of("a", "b", "c"));
list.getFirst();   // "a"(Java 21+)
list.getLast();    // "c"
list.addFirst("z");
list.removeLast();

// SequencedMap
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("one", 1);
map.put("two", 2);
map.firstEntry();   // Map.Entry{one=1}
map.lastEntry();    // Map.Entry{two=2}
map.reversed();     // 反转视图

CompletableFuture(Java 8,Java 21 虚拟线程加持)

import java.util.concurrent.CompletableFuture;

// 异步编排(避免回调地狱)
CompletableFuture<String> future = CompletableFuture
    .supplyAsync(() -> fetchUserName(userId))         // 异步获取用户名
    .thenApply(name -> "Hello, " + name)              // 同步转换
    .thenCompose(msg -> CompletableFuture              // 异步链式
        .supplyAsync(() -> sendEmail(msg)))
    .exceptionally(ex -> "Error: " + ex.getMessage()); // 异常处理

// 等待结果
String result = future.get();

// 组合多个异步任务
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> "World");

// 全部完成后执行
CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2);
all.thenRun(() -> System.out.println(f1.join() + " " + f2.join()));

// 任意一个完成后执行
CompletableFuture<Object> any = CompletableFuture.anyOf(f1, f2);

版本特性速查表

../../assets/05 Java 新特性速查/file 20260605123645396

Java 版本LTS核心新特性
8LTSLambda、Stream API、Optional、新时间 API(java.time)、默认方法、CompletableFuture
9模块化(Jigsaw)、JShell、集合工厂方法(List.of)、Stream 增强(takeWhile/dropWhile)
10var 局部变量类型推断
11LTSHTTP Client 正式版、String 新方法(strip/isBlank/lines)、Files.readString
12Switch 表达式(预览)
13文字块(预览)
14Switch 表达式正式版、Record(预览)、instanceof 模式匹配(预览)
15文字块正式版、Sealed Class(预览)
16Record 正式版、instanceof 模式匹配正式版
17LTSSealed Class 正式版、移除 Applet API
18UTF-8 默认编码
19虚拟线程(预览)、结构化并发(孵化)
20虚拟线程(第二次预览)、Switch 模式匹配(第四次预览)
21LTS虚拟线程正式版、Switch 模式匹配正式版、Sequenced Collections、字符串模板(预览)

参考资料

← 返回列表

评论 (0)

暂无评论,来留下第一条吧。
登录注册 后才能发表评论