跳到主要内容

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)和静态方法
  • 新的日期时间 APILocalDateLocalDateTimeZonedDateTime
  • 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 正式)

不可变数据类的语法糖,自动生成 equalshashCodetoString、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 CollectionsSequencedCollection/SequencedMap,提供 getFirst()/getLast()
  • String Templates(Preview)STR."Hello \{name}"

常见面试问题

Q1: Java 8 中最重要的新特性是什么?

答案

Lambda 表达式和 Stream API。Lambda 让 Java 支持函数式编程风格,Stream API 提供了声明式的集合操作。结合 OptionalCompletableFuture,Java 8 是 Java 发展史上变化最大的版本。

Q2: Lambda 表达式的本质是什么?

答案

Lambda 表达式是匿名函数式接口实例的语法糖。编译器不会为每个 Lambda 生成匿名内部类,而是使用 invokedynamic 指令 + LambdaMetafactory 在运行时动态生成实现类,性能优于匿名内部类。

Q3: Record 和 Lombok 的 @Data 有什么区别?

答案

维度RecordLombok @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)已全面支持。

相关链接