Skip to content
清晨的一缕阳光
返回

Java 8-21 新特性详解

Java 8-21 新特性详解

Java 8 是里程碑版本,引入了 Lambda 表达式和 Stream API。后续版本持续改进,Java 17 和 21 是 LTS 版本。

一、Java 8(2014 年)- 里程碑版本

1.1 Lambda 表达式

// 之前:匿名类
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello");
    }
}).start();

// Java 8:Lambda
new Thread(() -> System.out.println("Hello")).start();

// 函数式接口
@FunctionalInterface
interface Calculator {
    int calculate(int a, int b);
}

Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;

1.2 Stream API

List<String> list = Arrays.asList("a", "b", "c", "d");

// 过滤、转换、收集
List<String> result = list.stream()
    .filter(s -> !s.equals("b"))
    .map(String::toUpperCase)
    .collect(Collectors.toList());

// 归约
int sum = list.stream()
    .mapToInt(String::length)
    .sum();

// 分组
Map<Character, List<String>> grouped = list.stream()
    .collect(Collectors.groupingBy(s -> s.charAt(0)));

1.3 Optional

// 之前:嵌套 if 检查
if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        String city = address.getCity();
        if (city != null) {
            return city;
        }
    }
}
return "Unknown";

// Java 8:Optional
return Optional.ofNullable(user)
    .map(User::getAddress)
    .map(Address::getCity)
    .orElse("Unknown");

1.4 默认方法和静态方法

interface Collection {
    // 默认方法
    default void forEach(Consumer<? super T> action) {
        for (T element : this) {
            action.accept(element);
        }
    }
    
    // 静态方法
    static <T> List<T> of(T... elements) {
        return new ArrayList<>(Arrays.asList(elements));
    }
}

1.5 新的日期时间 API

// 不可变、线程安全
LocalDate date = LocalDate.of(2024, 1, 15);
LocalTime time = LocalTime.of(10, 30);
LocalDateTime dateTime = LocalDateTime.of(date, time);

// 时区
ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.of("Asia/Shanghai"));

// 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dateTime.format(formatter);

二、Java 9-11

2.1 模块系统(JDK 9)

// module-info.java
module com.example.myapp {
    requires java.sql;
    requires com.example.library;
    
    exports com.example.myapp.api;
}

2.2 集合工厂方法(JDK 9)

// 不可变集合
List<String> list = List.of("a", "b", "c");
Set<String> set = Set.of("a", "b", "c");
Map<String, Integer> map = Map.of("a", 1, "b", 2);

2.3 var 关键字(JDK 10)

// 局部变量类型推断
var list = new ArrayList<String>();
var map = new HashMap<String, Integer>();
var user = new User("Alice", 20);

// 限制
// var x; // 错误:必须初始化
// var x = null; // 错误:无法推断类型

2.4 String 新方法(JDK 11)

String str = "  Hello  ";

// strip(支持 Unicode)
str.strip();        // "Hello"
str.stripLeading(); // "Hello  "
str.stripTrailing(); // "  Hello"

// isBlank
str.isBlank(); // false

// lines
Stream<String> lines = str.lines();

// repeat
"Ha".repeat(3); // "HaHaHa"

三、Java 12-16

3.1 Switch 表达式(JDK 12/14)

// 之前:switch 语句
int days;
switch (month) {
    case 1: case 3: case 5: case 7: 
    case 8: case 10: case 12:
        days = 31;
        break;
    case 4: case 6: case 9: case 11:
        days = 30;
        break;
    case 2:
        days = isLeapYear ? 29 : 28;
        break;
}

// Java 14:switch 表达式
int days = switch (month) {
    case 1, 3, 5, 7, 8, 10, 12 -> 31;
    case 4, 6, 9, 11 -> 30;
    case 2 -> isLeapYear ? 29 : 28;
    default -> throw new IllegalArgumentException("Invalid month");
};

3.2 Text Blocks(JDK 15)

// 之前:转义麻烦
String json = "{\n" +
    "  \"name\": \"Alice\",\n" +
    "  \"age\": 20\n" +
    "}";

// Java 15:文本块
String json = """
    {
      "name": "Alice",
      "age": 20
    }
    """;

// SQL
String sql = """
    SELECT * FROM users
    WHERE age > ?
    ORDER BY name
    """;

3.3 Record(JDK 16)

// 之前:需要写很多代码
public class User {
    private final String name;
    private final int age;
    
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // getter、equals、hashCode、toString...
}

// Java 16:Record
public record User(String name, int age) {}

// 使用
User user = new User("Alice", 20);
String name = user.name(); // 自动 getter
System.out.println(user);  // User[name=Alice, age=20]

3.4 Pattern Matching(JDK 16)

// 之前:需要强制转换
if (obj instanceof String) {
    String str = (String) obj;
    System.out.println(str.length());
}

// Java 16:模式匹配
if (obj instanceof String str) {
    System.out.println(str.length());
}

四、Java 17-21(LTS 版本)

4.1 Sealed Classes(JDK 17)

// 限制哪些类可以继承
public sealed class Shape permits Circle, Rectangle, Triangle {}

public final class Circle extends Shape {
    private final double radius;
}

public final class Rectangle extends Shape {
    private final double width, height;
}

public final class Triangle extends Shape {
    private final double base, height;
}

// 配合模式匹配
public 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.5 * t.base() * t.height();
    };
}

4.2 增强的 switch(JDK 17+)

// 模式匹配 + switch
String format(Object obj) {
    return switch (obj) {
        case Integer i -> "Integer: " + i;
        case String s -> "String: " + s;
        case List<?> l -> "List: " + l.size() + " elements";
        case null -> "null";
        default -> "Unknown";
    };
}

4.3 虚拟线程(JDK 21)

// 轻量级线程,百万级并发
// 之前:平台线程(昂贵)
ExecutorService executor = Executors.newFixedThreadPool(100);

// Java 21:虚拟线程
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();

// 直接使用
Thread.startVirtualThread(() -> {
    System.out.println("Running in virtual thread");
});

// 大规模并发
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    List<Future<Integer>> futures = new ArrayList<>();
    
    for (int i = 0; i < 1_000_000; i++) {
        futures.add(executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return 1;
        }));
    }
    
    int sum = futures.stream()
        .mapToInt(f -> f.get())
        .sum();
}

4.4 Record Patterns(JDK 21)

// Record 嵌套
public record Point(int x, int y) {}
public record ColoredPoint(Point p, Color c) {}

// 模式匹配解构
void process(ColoredPoint cp) {
    if (cp instanceof ColoredPoint(Point(int x, int y), Color c)) {
        System.out.println("x=" + x + ", y=" + y + ", color=" + c);
    }
}

// switch 中解构
String describe(ColoredPoint cp) {
    return switch (cp) {
        case ColoredPoint(Point(int x, int y), Color c) 
            when x > 0 && y > 0 -> "First quadrant";
        case ColoredPoint(Point(int x, int y), _) 
            when x < 0 -> "Left side";
        default -> "Other";
    };
}

五、版本选择建议

版本类型推荐度说明
Java 8LTS⭐⭐⭐⭐⭐最广泛使用,生态完善
Java 11LTS⭐⭐⭐⭐性能提升,HTTP Client
Java 17LTS⭐⭐⭐⭐⭐Record、Sealed Classes
Java 21LTS⭐⭐⭐⭐⭐虚拟线程、模式匹配

六、总结

Java 8-21 核心特性:

版本核心特性
Java 8Lambda、Stream、Optional、新日期 API
Java 9模块系统、集合工厂、Optional 增强
Java 11var、String 新方法、HttpClient
Java 14-16Switch 表达式、文本块、Record
Java 17Sealed Classes、增强的 switch
Java 21虚拟线程、模式匹配、Record Patterns

Java 8 是必学版本,Java 17/21 是新项目首选,虚拟线程将改变并发编程范式。


分享这篇文章到:

上一篇文章
慢查询日志与优化
下一篇文章
Go Mutex 互斥锁底层原理