# Java版本新特性全解析:从Java 5到Java 21
> Java的发展历程是一部不断演进的技术史诗。从2004年的Java 5到2023年的Java 21,每个版本都在推动着Java生态向前发展。
---
## 前言
Java自1995年诞生以来,经历了多个重要版本。本文将系统梳理从Java 5到Java 21(最新LTS版本)的所有重要新特性,帮助你全面了解Java的演进历程。
**版本分类说明**:
- **LTS(长期支持)版本**:Java 8, 11, 17, 21 - 生产环境推荐使用
- **非LTS版本**:6个月更新周期,适合尝鲜和学习
---
## Java 5(代号:Tiger)- 2004年
Java 5是Java历史上最重要的版本之一,引入了大量革命性特性。
### 核心特性
#### 1. 泛型(Generics)
```java
// 泛型集合
List
names = new ArrayList();
names.add("Java");
// 泛型方法
public T findFirst(List list) {
return list.isEmpty() ? null : list.get(0);
}
// 泛型类
class Box {
private T item;
public void set(T item) { this.item = item; }
public T get() { return item; }
}
```
**意义**:编译时类型检查,避免ClassCastException
#### 2. 增强for循环(For-Each Loop)
```java
List languages = Arrays.asList("Java", "Python", "Go");
// 传统方式
for (int i = 0; i < languages.size(); i++) {
System.out.println(languages.get(i));
}
// 增强for循环
for (String lang : languages) {
System.out.println(lang);
}
```
#### 3. 自动装箱/拆箱(Autoboxing/Unboxing)
```java
// 自动装箱
Integer a = 100; // 相当于 Integer.valueOf(100)
// 自动拆箱
int b = a; // 相当于 a.intValue()
// 集合中使用
List numbers = new ArrayList<>();
numbers.add(10); // 自动装箱
int sum = numbers.get(0); // 自动拆箱
```
#### 4. 枚举(Enum)
```java
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
// 枚举可以包含方法和字段
private String description;
Day() {
this.description = "Day of week";
}
}
// 使用
Day today = Day.MONDAY;
switch (today) {
case MONDAY:
System.out.println("Start of week");
break;
}
```
#### 5. 可变参数(Varargs)
```java
public void printAll(String... args) {
for (String arg : args) {
System.out.println(arg);
}
}
// 使用
printAll("Hello", "World", "Java");
printAll("Single argument");
printAll(); // 空参数
```
#### 6. 静态导入(Static Import)
```java
import static java.lang.Math.*;
import static java.util.Collections.*;
public class Demo {
public void test() {
double value = sqrt(25.0); // 不需要 Math.sqrt(25.0)
List list = new ArrayList<>();
sort(list); // 不需要 Collections.sort(list)
}
}
```
#### 7. 注解(Annotations)
```java
// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value() default "";
int priority() default 0;
}
// 使用注解
public class Demo {
@MyAnnotation(value = "Important method", priority = 1)
public void importantMethod() {
System.out.println("This is important!");
}
}
```
#### 8. 并发包(java.util.concurrent)
```java
// 线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> System.out.println("Task executed"));
executor.shutdown();
// 并发集合
ConcurrentHashMap map = new ConcurrentHashMap<>();
CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
// 原子类
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet();
```
---
## Java 6(代号:Mustang)- 2006年
Java 6主要关注性能优化和API增强。
### 核心特性
#### 1. JDBC 4.0
```java
// 无需显式加载驱动
// Class.forName("com.mysql.jdbc.Driver"); // 不再需要
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb", "user", "password"
);
```
#### 2. StAX(Streaming API for XML)
```java
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream("file.xml"));
while (reader.hasNext()) {
int event = reader.next();
if (event == XMLStreamConstants.START_ELEMENT) {
System.out.println("Element: " + reader.getLocalName());
}
}
```
#### 3. 脚本引擎支持(JSR 223)
```java
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
engine.eval("print('Hello from JavaScript!')");
Object result = engine.eval("10 + 20");
System.out.println("Result: " + result);
```
#### 4. Compiler API
```java
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable extends JavaFileObject> compilationUnits =
fileManager.getJavaFileObjectsFromStrings(Arrays.asList("MyClass.java"));
compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
```
#### 5. 性能优化
- 改进的锁机制
- 更好的垃圾回收器
- 类数据共享(Class Data Sharing)
---
## Java 7(代号:Dolphin)- 2011年
Java 7引入了许多语法糖和实用特性。
### 核心特性
#### 1. 二进制字面量
```java
int binary = 0b10101010; // 二进制表示
int binary2 = 0B1010_1010; // 支持下划线分隔
int hex = 0x2A; // 十六进制
```
#### 2. 数字字面量中的下划线
```java
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
double pi = 3.141_592_653_589_793d;
```
#### 3. switch语句支持String
```java
String day = "MONDAY";
switch (day) {
case "MONDAY":
System.out.println("Start of week");
break;
case "FRIDAY":
System.out.println("Almost weekend");
break;
default:
System.out.println("Mid week");
}
```
#### 4. 泛型实例化类型推断(Diamond Operator)
```java
// 旧方式
Map> map = new HashMap>();
// 新方式 - 菱形操作符
Map> map = new HashMap<>();
List list = new ArrayList<>();
```
#### 5. try-with-resources
```java
// 旧方式
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
// 读取文件
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 新方式
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
// 读取文件,资源自动关闭
} catch (IOException e) {
e.printStackTrace();
}
// 多个资源
try (FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt")) {
// 自动关闭两个资源
}
```
#### 6. 捕获多个异常
```java
// 旧方式
try {
// 代码
} catch (IOException e) {
handleException(e);
} catch (SQLException e) {
handleException(e);
}
// 新方式
try {
// 代码
} catch (IOException | SQLException e) {
handleException(e);
}
```
#### 7. NIO.2(New I/O 2)
```java
// Path API
Path path = Paths.get("/home/user/documents/file.txt");
Path absolutePath = path.toAbsolutePath();
Path parent = path.getParent();
Path fileName = path.getFileName();
// 文件操作
Files.createFile(Paths.get("newfile.txt"));
Files.createDirectory(Paths.get("newdir"));
Files.copy(Paths.get("source.txt"), Paths.get("dest.txt"));
Files.delete(Paths.get("file.txt"));
// 文件遍历
Files.walk(Paths.get("/home/user"))
.filter(p -> p.toString().endsWith(".java"))
.forEach(System.out::println);
// 监控文件系统变化
WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = Paths.get("/home/user/watch");
dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
```
#### 8. Fork/Join框架
```java
class Fibonacci extends RecursiveTask {
private final int n;
public Fibonacci(int n) {
this.n = n;
}
@Override
protected Integer compute() {
if (n <= 1) {
return n;
}
Fibonacci f1 = new Fibonacci(n - 1);
f1.fork();
Fibonacci f2 = new Fibonacci(n - 2);
return f2.compute() + f1.join();
}
}
// 使用
ForkJoinPool pool = new ForkJoinPool();
int result = pool.invoke(new Fibonacci(10));
```
---
## Java 8(代号:Spider)- 2014年 ⭐ LTS
Java 8是Java历史上最革命性的版本,引入了函数式编程特性。
### 核心特性
#### 1. Lambda表达式
```java
// 旧方式 - 匿名内部类
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello from anonymous class");
}
};
// 新方式 - Lambda表达式
Runnable r2 = () -> System.out.println("Hello from lambda");
// Lambda表达式语法
// 参数 -> 表达式
// (参数) -> { 语句; }
// (参数1, 参数2) -> { 语句1; 语句2; }
// 函数式接口
@FunctionalInterface
interface MathOperation {
int operate(int a, int b);
}
MathOperation addition = (a, b) -> a + b;
MathOperation multiplication = (a, b) -> a * b;
System.out.println(addition.operate(5, 3)); // 8
```
#### 2. 方法引用
```java
List names = Arrays.asList("Alice", "Bob", "Charlie");
// 静态方法引用
names.forEach(System.out::println);
// 实例方法引用
names.stream()
.map(String::toLowerCase)
.forEach(System.out::println);
// 构造器引用
Supplier> listSupplier = ArrayList::new;
List newList = listSupplier.get();
// 特定对象的方法引用
String prefix = "Hello, ";
Function addPrefix = prefix::concat;
```
#### 3. Stream API
```java
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 过滤和映射
List evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.collect(Collectors.toList());
// 结果: [4, 8, 12, 16, 20]
// 求和
int sum = numbers.stream()
.reduce(0, Integer::sum);
// 分组
Map> grouped = numbers.stream()
.collect(Collectors.groupingBy(n -> n % 2 == 0));
// 查找
Optional first = numbers.stream()
.filter(n -> n > 5)
.findFirst();
// 统计
IntSummaryStatistics stats = numbers.stream()
.mapToInt(Integer::intValue)
.summaryStatistics();
System.out.println("Max: " + stats.getMax());
System.out.println("Average: " + stats.getAverage());
// 并行流
long count = numbers.parallelStream()
.filter(n -> n > 5)
.count();
```
#### 4. Optional类
```java
// 避免NullPointerException
Optional optional = Optional.of("Hello");
// 判断是否存在
if (optional.isPresent()) {
System.out.println(optional.get());
}
// orElse - 提供默认值
String value = optional.orElse("Default Value");
// orElseGet - 延迟提供默认值
String value2 = optional.orElseGet(() -> computeDefault());
// orElseThrow - 为空时抛出异常
String value3 = optional.orElseThrow(() -> new IllegalArgumentException("Value not present"));
// map转换
Optional length = optional.map(String::length);
// flatMap - 避免嵌套Optional
Optional result = optional.flatMap(s -> Optional.of(s.toUpperCase()));
// ifPresent - 存在时执行操作
optional.ifPresent(System.out::println);
// 创建Optional
Optional nonNull = Optional.of("Value");
Optional nullable = Optional.ofNullable(null); // Optional.empty
Optional empty = Optional.empty();
```
#### 5. 新的日期时间API(java.time)
```java
// LocalDate - 日期(年月日)
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1990, Month.JANUARY, 15);
LocalDate parsed = LocalDate.parse("2024-03-15");
// LocalTime - 时间(时分秒)
LocalTime now = LocalTime.now();
LocalTime specificTime = LocalTime.of(14, 30, 45);
LocalTime parsedTime = LocalTime.parse("14:30:45");
// LocalDateTime - 日期时间
LocalDateTime dateTime = LocalDateTime.now();
LocalDateTime specificDateTime = LocalDateTime.of(2024, 3, 15, 14, 30);
// ZonedDateTime - 带时区的时间
ZonedDateTime zonedTime = ZonedDateTime.now();
ZonedDateTime parisTime = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
// Duration - 时间段
Duration duration = Duration.between(LocalTime.NOON, LocalTime.now());
// Period - 日期段
Period period = Period.between(birthday, today);
// DateTimeFormatter - 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dateTime.format(formatter);
// 日期计算
LocalDate nextWeek = today.plusWeeks(1);
LocalDate previousMonth = today.minusMonths(1);
LocalDate nextYear = today.plusYears(1);
// 日期比较
boolean isBefore = birthday.isBefore(today);
boolean isAfter = today.isAfter(birthday);
// 调整日期
LocalDate firstDayOfMonth = today.withDayOfMonth(1);
LocalDate lastDayOfYear = today.withDayOfYear(365);
```
#### 6. 接口默认方法和静态方法
```java
public interface Vehicle {
// 抽象方法
String start();
// 默认方法
default void stop() {
System.out.println("Vehicle stopped");
}
// 静态方法
static void info() {
System.out.println("This is a vehicle interface");
}
}
// 实现类可以选择是否覆盖默认方法
class Car implements Vehicle {
@Override
public String start() {
return "Car started";
}
// 使用默认的stop方法
}
// 使用
Car car = new Car();
car.start(); // "Car started"
car.stop(); // "Vehicle stopped" - 使用默认方法
Vehicle.info(); // "This is a vehicle interface"
```
#### 7. 重复注解
```java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Authors {
Author[] value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(Authors.class)
public @interface Author {
String name();
String email();
}
@Author(name = "John", email = "john@example.com")
@Author(name = "Jane", email = "jane@example.com")
public class MyBook {
// 类定义
}
// 读取重复注解
Authors authors = MyBook.class.getAnnotation(Authors.class);
for (Author author : authors.value()) {
System.out.println(author.name() + " - " + author.email());
}
```
#### 8. CompletableFuture
```java
// 异步执行
CompletableFuture future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "Hello";
});
// thenApply - 转换结果
CompletableFuture lengthFuture = future.thenApply(String::length);
// thenAccept - 消费结果
CompletableFuture voidFuture = future.thenAccept(System.out::println);
// thenRun - 不依赖结果的后续操作
CompletableFuture runFuture = future.thenRun(() -> System.out.println("Done!"));
// 组合多个Future
CompletableFuture future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture future2 = CompletableFuture.supplyAsync(() -> "World");
CompletableFuture combined = future1.thenCombine(future2, (s1, s2) -> s1 + " " + s2);
// 等待结果
String result = combined.get(); // "Hello World"
// 异常处理
CompletableFuture futureWithException = CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("Something went wrong");
}
return "Success";
}).exceptionally(ex -> {
System.err.println("Exception: " + ex.getMessage());
return "Default Value";
});
```
#### 9. Base64编码
```java
import java.util.Base64;
String original = "Hello, World!";
// 编码
String encoded = Base64.getEncoder().encodeToString(original.getBytes());
// "SGVsbG8sIFdvcmxkIQ=="
// 解码
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes);
// "Hello, World!"
// URL编码
String urlEncoded = Base64.getUrlEncoder().withoutPadding()
.encodeToString(original.getBytes());
// MIME编码
String mimeEncoded = Base64.getMimeEncoder()
.encodeToString(original.getBytes());
```
#### 10. 并行数组排序
```java
int[] array = {5, 2, 8, 1, 9, 3};
// 串行排序
Arrays.sort(array);
// 并行排序 - 适合大数组
Arrays.parallelSort(array);
// 并行排序数组的一部分
int[] largeArray = new int[1000000];
Arrays.fill(largeArray, 1);
Arrays.parallelSort(largeArray, 0, 500000); // 只排序前50万个元素
```
---
## Java 9 - 2017年
Java 9是模块化时代的开始,引入了Jigsaw项目。
### 核心特性
#### 1. 模块化系统(Jigsaw)
```java
// 模块描述文件 module-info.java
module com.example.myapp {
requires java.base; // 默认依赖
requires java.logging; // 显式依赖
exports com.example.myapp.api; // 导出包
exports com.example.myapp.service to com.example.other; // 限定导出
uses com.example.myapp.spi.Service; // 使用服务
provides com.example.myapp.spi.Service with com.example.myapp.impl.ServiceImpl; // 提供服务
}
```
**模块化命令**:
```bash
# 编译模块
javac --module-source-path src -d out --module myapp
# 运行模块
java --module-path out --module myapp/com.example.myapp.Main
# 列出模块
java --list-modules
# 描述模块
java --describe-module java.base
```
#### 2. JShell - Java REPL
```bash
# 启动JShell
jshell
# 执行代码
jshell> int x = 10;
x ==> 10
jshell> System.out.println(x * 2);
20
jshell> List list = new ArrayList<>();
list ==> []
jshell> list.add("Java");
$3 ==> true
jshell> list
[$1 -> "Java"]
# 退出
jshell> /exit
```
#### 3. 不可变集合工厂方法
```java
// List.of() - 创建不可变List
List immutableList = List.of("Java", "Python", "Go");
immutableList.add("C++"); // UnsupportedOperationException
// Set.of() - 创建不可变Set
Set immutableSet = Set.of(1, 2, 3, 4, 5);
immutableSet.add(6); // UnsupportedOperationException
// Map.of() - 创建不可变Map(最多10个键值对)
Map map1 = Map.of("Alice", 25, "Bob", 30);
// Map.ofEntries() - 创建不可变Map(无键值对数量限制)
Map map2 = Map.ofEntries(
Map.entry("Alice", 25),
Map.entry("Bob", 30),
Map.entry("Charlie", 35)
);
// 比较旧的Collections.unmodifiableXXX()
List oldWay = Collections.unmodifiableList(new ArrayList<>(Arrays.asList("A", "B")));
List newWay = List.of("A", "B");
```
#### 4. Stream API增强
```java
// takeWhile() - 取满足条件的元素
Stream stream1 = Stream.of(1, 2, 3, 4, 5, 6);
stream1.takeWhile(n -> n < 4).forEach(System.out::println); // 1, 2, 3
// dropWhile() - 丢弃满足条件的元素
Stream stream2 = Stream.of(1, 2, 3, 4, 5, 6);
stream2.dropWhile(n -> n < 4).forEach(System.out::println); // 4, 5, 6
// ofNullable() - 避免NullPointerException
Stream stream3 = Stream.ofNullable("Hello"); // Stream
Stream stream4 = Stream.ofNullable(null); // Empty stream
// iterate() - 新的重载方法
Stream.iterate(0, n -> n < 10, n -> n + 2).forEach(System.out::println); // 0, 2, 4, 6, 8
```
#### 5. Optional类增强
```java
// ifPresentOrElse() - 存在和不存在的处理
Optional optional = Optional.of("Java");
optional.ifPresentOrElse(
value -> System.out.println("Value: " + value),
() -> System.out.println("Value not present")
);
// or() - 提供Supplier作为后备
Optional result = optional.or(() -> Optional.of("Default"));
// stream() - 转换为Stream
optional.stream().forEach(System.out::println);
```
#### 6. 响应式流(Reactive Streams)
```java
import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;
// 发布者
SubmissionPublisher publisher = new SubmissionPublisher<>();
// 订阅者
Flow.Subscriber subscriber = new Flow.Subscriber<>() {
private Flow.Subscription subscription;
@Override
public void onSubscribe(Flow.Subscription subscription) {
this.subscription = subscription;
subscription.request(1); // 请求一个元素
}
@Override
public void onNext(String item) {
System.out.println("Received: " + item);
subscription.request(1); // 请求下一个元素
}
@Override
public void onError(Throwable throwable) {
System.err.println("Error: " + throwable.getMessage());
}
@Override
public void onComplete() {
System.out.println("Completed");
}
};
// 订阅
publisher.subscribe(subscriber);
// 发布消息
publisher.submit("Hello");
publisher.submit("World");
publisher.close();
```
#### 7. 私有接口方法
```java
public interface MyInterface {
default void method1() {
commonMethod();
System.out.println("Method 1");
}
default void method2() {
commonMethod();
System.out.println("Method 2");
}
// 私有方法 - 只能在接口内部使用
private void commonMethod() {
System.out.println("Common logic");
}
// 私有静态方法
private static void staticHelper() {
System.out.println("Static helper");
}
}
```
#### 8. Process API
```java
// 获取当前进程
ProcessHandle currentProcess = ProcessHandle.current();
System.out.println("PID: " + currentProcess.pid());
System.out.println("Command: " + currentProcess.info().command().orElse("N/A"));
// 获取所有进程
ProcessHandle.allProcesses()
.filter(ph -> ph.info().command().map(c -> c.contains("java")).orElse(false))
.forEach(ph -> System.out.println(ph.pid()));
// 启动新进程
ProcessBuilder pb = new ProcessBuilder("notepad.exe");
Process process = pb.start();
ProcessHandle processHandle = process.toHandle();
processHandle.onExit().thenRun(() -> System.out.println("Process exited"));
```
#### 9. 变量句柄(VarHandle)
```java
import java.lang.invoke.VarHandle;
class MyClass {
private volatile int value = 0;
private static final VarHandle VALUE_HANDLE;
static {
try {
VALUE_HANDLE = MethodHandles.lookup()
.findVarHandle(MyClass.class, "value", int.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public void setValue(int newValue) {
VALUE_HANDLE.setVolatile(this, newValue);
}
public int getValue() {
return (int) VALUE_HANDLE.getVolatile(this);
}
}
```
#### 10. HTTP/2客户端
```java
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
// HTTP客户端(Java 9时还是incubator)
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/data"))
.GET()
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```
---
## Java 10 - 2018年
Java 10是一个小版本,主要聚焦于性能改进和局部变量类型推断。
### 核心特性
#### 1. 局部变量类型推断(var)
```java
// 基本用法
var name = "Java"; // 推断为 String
var age = 25; // 推断为 int
var list = new ArrayList(); // 推断为 ArrayList
var map = Map.of("key", "value"); // 推断为 Map
// 在循环中使用
for (var item : list) {
System.out.println(item);
}
// 在try-with-resources中使用
try (var reader = new BufferedReader(new FileReader("file.txt"))) {
// reader推断为BufferedReader
}
// 在Lambda中作为返回类型
Supplier