Java 新特性
问题
Java 8 到 Java 21 有哪些重要的新特性?
答案
Java 8(2014)— 最重要的一个版本
Lambda 表达式
LambdaDemo.java
// 之前:匿名内部类
Comparator<String> comp = new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.length() - b.length();
}
};
// Lambda 表达式:简洁的函数式写法
Comparator<String> comp = (a, b) -> a.length() - b.length();
// 方法引用:更简洁
list.forEach(System.out::println);
函数式接口
| 接口 | 方法 | 说明 |
|---|---|---|
Function<T, R> | R apply(T t) | 输入 T,输出 R |
Predicate<T> | boolean test(T t) | 输入 T,返回布尔值 |
Consumer<T> | void accept(T t) | 输入 T,无返回值 |
Supplier<T> | T get() | 无输入,返回 T |
Stream API
StreamDemo.java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> result = names.stream()
.filter(name -> name.length() > 3) // 过滤
.map(String::toUpperCase) // 转换
.sorted() // 排序
.collect(Collectors.toList()); // 收集
// [ALICE, CHARLIE, DAVID]
Optional
Optional<String> opt = Optional.ofNullable(getName());
String name = opt
.filter(n -> n.length() > 0)
.map(String::toUpperCase)
.orElse("UNKNOWN");
其他
- 接口默认方法(
default)和静态方法 - 新的日期时间 API:
LocalDate、LocalDateTime、ZonedDateTime - CompletableFuture:异步编程
Java 11(2018)— 首个长期支持版(LTS)
// var 局部变量类型推断(Java 10 引入,11 可用于 Lambda 参数)
var list = new ArrayList<String>();
list.stream().map((var s) -> s.toUpperCase()); // Lambda 中使用 var
// String 新方法
" hello ".strip(); // "hello"(支持 Unicode 空白)
" hello ".isBlank(); // false
"hello\nworld".lines(); // Stream<String>
"ha".repeat(3); // "hahaha"
// HttpClient(标准化)
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com"))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
// 直接运行 .java 文件
// java HelloWorld.java (无需先 javac)
Java 14-16 — Record、Pattern Matching
Record(Java 16 正式)
不可变数据类的语法糖,自动生成 equals、hashCode、toString、getter:
RecordDemo.java
// 之前:需要大量样板代码(字段、构造器、getter、equals、hashCode、toString)
// 现在:一行搞定
public record Point(int x, int y) { }
Point p = new Point(1, 2);
System.out.println(p.x()); // 1(getter 方法名是字段名,不是 getX)
System.out.println(p); // Point[x=1, y=2]
// 可以自定义紧凑构造器(Compact Constructor)做校验
public record Range(int min, int max) {
public Range {
if (min > max) throw new IllegalArgumentException("min > max");
}
}
instanceof 模式匹配(Java 16 正式)
// 之前
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// 现在:直接绑定变量
if (obj instanceof String s) {
System.out.println(s.length());
}
Java 17(2021)— LTS
Sealed Classes(密封类)
限制哪些类可以继承/实现:
SealedClassDemo.java
// 只有 Circle、Rectangle、Triangle 可以继承 Shape
public sealed class Shape permits Circle, Rectangle, Triangle { }
public final class Circle extends Shape { } // final:不能再继承
public sealed class Rectangle extends Shape // sealed:限制子类
permits Square { }
public non-sealed class Triangle extends Shape { } // non-sealed:开放继承
public final class Square extends Rectangle { }
Switch 增强
// 箭头语法 + 不需要 break
String result = switch (day) {
case MONDAY, FRIDAY -> "工作日";
case SATURDAY, SUNDAY -> "周末";
default -> "未知";
};
Java 21(2023)— LTS
Virtual Threads(虚拟线程)
轻量级线程,解决了 "一请求一线程" 模型的性能瓶颈:
VirtualThreadDemo.java
// 创建虚拟线程
Thread vThread = Thread.ofVirtual().start(() -> {
System.out.println("Running in virtual thread");
});
// 虚拟线程执行器:可以轻松创建百万级线程
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 1_000_000; i++) {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return "done";
});
}
} // 自动关闭
| 维度 | 平台线程 | 虚拟线程 |
|---|---|---|
| 创建成本 | 约 1MB 栈内存 | 约几 KB |
| 数量上限 | 数千 | 数百万 |
| 调度 | OS 内核调度 | JVM 用户态调度 |
| 适用场景 | CPU 密集 | IO 密集 |
Pattern Matching for switch
static String format(Object obj) {
return switch (obj) {
case Integer i -> "整数: " + i;
case String s -> "字符串: " + s;
case null -> "null";
default -> "其他: " + obj;
};
}
其他 Java 21 特性
- Sequenced Collections:
SequencedCollection/SequencedMap,提供getFirst()/getLast() - String Templates(Preview):
STR."Hello \{name}"
常见面试问题
Q1: Java 8 中最重要的新特性是什么?
答案:
Lambda 表达式和 Stream API。Lambda 让 Java 支持函数式编程风格,Stream API 提供了声明式的集合操作。结合 Optional 和 CompletableFuture,Java 8 是 Java 发展史上变化最大的版本。
Q2: Lambda 表达式的本质是什么?
答案:
Lambda 表达式是匿名函数式接口实例的语法糖。编译器不会为每个 Lambda 生成匿名内部类,而是使用 invokedynamic 指令 + LambdaMetafactory 在运行时动态生成实现类,性能优于匿名内部类。
Q3: Record 和 Lombok 的 @Data 有什么区别?
答案:
| 维度 | Record | Lombok @Data |
|---|---|---|
| 可变性 | 不可变(字段 final) | 可变(有 setter) |
| 继承 | 不能继承其他类(隐式继承 Record) | 可以继承 |
| 语言级别 | JDK 原生支持 | 第三方编译器插件 |
| getter 命名 | name()(不带 get 前缀) | getName() |
| 适用场景 | DTO、值对象 | 可变实体类 |
Q4: Virtual Thread 和传统线程池有什么区别?
答案:
Virtual Thread 适合 IO 密集型任务(网络请求、数据库查询),可以创建百万级虚拟线程而不会耗尽系统资源。传统线程池适合 CPU 密集型任务。
// 传统方式:线程池控制并发
ExecutorService pool = Executors.newFixedThreadPool(200);
// Virtual Thread:不需要池化,直接创建
ExecutorService vPool = Executors.newVirtualThreadPerTaskExecutor();
// 每个任务一个虚拟线程,IO 阻塞时自动让出载体线程
Q5: 你认为 Java 最值得升级到哪个版本?
答案:
从生态和稳定性角度,推荐升级路线:
- Java 8 → Java 17:获得 Record、Sealed Class、文本块、instanceof 模式匹配等
- Java 17 → Java 21:获得虚拟线程、Pattern Matching for switch、Sequenced Collections
Java 21 是最新的 LTS 版本,大多数主流框架(Spring Boot 3.2+、Quarkus)已全面支持。