> ## Documentation Index
> Fetch the complete documentation index at: https://blog.pig4cloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Java24

> 🚀 Java 24 正式发布！作为 JDK 25（下一个 LTS 版本）的重要铺垫，这次更新带来了哪些令人兴奋的新特性？让我们一起探索 Java 开发的新世界！

## 🎯 为什么 JDK 24 如此重要？

JDK 24 是一个具有里程碑意义的版本，因为这次更新中包含的 JEP（JDK 增强提案）候选功能很有可能成为**JDK 25**的正式特性。而 JDK 25 将在**2025 年 9 月**发布，成为继 JDK 21 之后的下一个**长期支持（LTS）版本**。

## 1. 🎉 简化的 Hello World：告别繁琐语法

**终于来了！** Java 现在支持简单的`void main()`方法来打印"Hello, World"！

### 传统写法 vs 新写法

**JDK 21 及之前的传统写法：**

```java theme={null}
public class MyFirstClass {
    public static void main(String[] args) {
        System.out.println("Hello, World");
    }
}
```

❌ **痛点**：对于 Java 初学者来说，这种冗长的代码难以理解，特别是对那些不熟悉 Java 语法的人。

**JDK 24 的新写法：**

```java theme={null}
void main() {
    println("Hello, World");
}
```

⚠️ **注意**：这不是全新的 Java 语法——有经验的 Java 开发者仍然可以使用所有现有的语法和详细写法。

👉 **实现原理**：JVM 通过隐式声明类和实例方法来实现这一功能。同时，JVM 现在会在运行时自动导入某些必需的包，减少了使用`println()`等实用方法时的手动命名空间声明需求。

### 实际应用示例

下面的程序从控制台读取用户姓名并打印问候消息：

```java theme={null}
void main() {
    var name = readln();
    var message = "Hello, World and " + name;
    println(message);
}
```

如果转换为传统的 Java 代码，等价于：

```java theme={null}
import java.io.*;
import java.util.Scanner;

public class A {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String name = sc.nextLine();
        String message = "Hello, World and " + name;
        System.out.println(message);
        sc.close();
    }
}
```

🔗 **相关 JEP**：[JEP 495 - 简单源文件和实例主方法](https://openjdk.org/jeps/495)

***

## 2. 🔍 原始类型模式匹配：instanceof 和 Switch 的新玩法

### 解决的问题

❌ **JDK 21 的限制**：类型匹配要求被比较的变量必须是引用类型，而不能是原始类型。

👉 **JDK 24 的改进**：从 JDK 24 开始，`instanceof`和`switch-case`中的类型匹配将允许对象与原始类型匹配，而不仅仅是引用类型。

### instanceof 示例

```java theme={null}
public class Test {
    public static String identifyType(Object value) {
        if (value instanceof int) {
            return String.format("int: %d", value);
        } else if (value instanceof String) {
            return String.format("String: %s", value);
        } else if (value instanceof Double) {
            return String.format("Double: %f", value);
        } else {
            return "Unknown type";
        }
    }
}
```

### Switch-Case 示例

```java theme={null}
String identifyType(Object value) {
    return switch (value) {
        case int i -> String.format("int: %d", i);      // 原始类型！
        case Double d -> String.format("Double: %f", d);
        case String s -> String.format("String: %s", s);
        default -> "Unknown type";
    };
}
```

🔗 **相关 JEP**：[JEP 488 - 模式中的原始类型](https://openjdk.org/jeps/488)

***

## 3. 🏗️ 灵活的构造函数体：突破 super() 限制

👉 **新特性**：开发者现在可以在构造函数体中使用`super()`初始化父类之前包含逻辑代码。

❌ **JDK 21 的限制**：这是不可能的——开发者必须在父类中使用辅助方法来在初始化后执行逻辑。

### 构造函数的新结构

构造函数体现在分为两部分：**序言（Prologue）**和**尾声（Epilogue）**。

```java theme={null}
public class A extends B {
    public A() {
        // 序言 - 可以在 super() 之前执行逻辑
        super();
        // 尾声 - super() 之后的逻辑
    }
}
```

⚠️ **重要限制**：在序言阶段，无法访问正在初始化的当前实例。

### 实际应用示例

```java theme={null}
public class A extends B {
    private static int multiplier = 10;
    private final int childValue;

    public A(int baseValue) {
        // 序言 - 计算逻辑
        int computedValue = baseValue * multiplier;

        super(baseValue); // 初始化父类 B

        // 尾声 - 设置子类属性
        this.childValue = computedValue;
    }
}
```

🔗 **相关 JEP**：[JEP 492 - 灵活的构造函数体](https://openjdk.org/jeps/492)

***

## 4. 🔒 作用域值：ThreadLocal 的完美替代品

### 解决 ThreadLocal 的三大痛点

`ScopedValue` API 是对`ThreadLocal` API 的改进，用于在不同线程（包括虚拟线程）和任务之间共享不可变数据。

👉 **ScopedValue 解决的三个关键挑战**：

1. **可变性问题**：ThreadLocal 中，线程既可以访问又可以修改共享变量，导致意外副作用。ScopedValue 只允许共享不可变数据。

2. **无界生命周期**：ThreadLocal 变量必须手动移除。ScopedValue 在原始拥有线程完成执行后自动清理。

3. **昂贵的继承**：ThreadLocal 变量必须为子线程复制和重新创建。ScopedValue 允许父子线程之间高效共享内存。

### 使用示例

```java theme={null}
static final ScopedValue<String> USERNAME = ScopedValue.newInstance();

void main(String[] args) {
    ScopedValue.where(USERNAME, "Amrit").run(() -> {
        System.out.println("主任务中的值：" + USERNAME.get());
        performSubTask();
    });
}

static void performSubTask() {
    System.out.println("子任务中的值：" + USERNAME.get());
}
```

🔗 **相关 JEP**：[JEP 487 - 作用域值](https://openjdk.org/jeps/487)

***

## 5. 📦 模块导入声明：告别重复导入

### 批量导入的新方式

👉 **新特性**：用户现在可以直接导入一组相关包，而不是单独导入它们。

这减少了冗长性，并消除了重复包导入造成的低效率。

### 对比示例

**传统方式**：

```java theme={null}
import javax.xml.*;
import javax.xml.parsers.*;
import javax.xml.stream.*;
```

**新方式**：

```java theme={null}
import module java.xml;
```

👉 **其他可用模块**：`java.base`、`java.desktop`、`java.sql`等，每个模块都为特定用例分组了所需的包。

🔗 **相关 JEP**：[JEP 494 - 模块导入声明](https://openjdk.org/jeps/494)

***

## 6. 🏗️ 结构化并发：并发编程的新范式

### 解决并发编程的结构化问题

JDK 24 引入的`StructuredTask` API 将并发编程中的子任务组合在一起，在运行时将它们视为一个单元，而不是独立的任务。

❌ **ExecutorService 的问题**：使用传统的 ExecutorService API，子任务与启动它们的父任务只有逻辑关系，在运行时独立运行，没有直接连接。

👉 **StructuredTask 的优势**：开发者现在可以控制整个任务，该任务可以由在不同任务中运行的子任务组成为一个整体单元。如果一个任务失败，失败会传播到其他依赖任务，整个任务也会中止。

### 代码对比示例

```java theme={null}
import java.util.concurrent.*;

Integer fun1() throws Exception {
    Integer val = 1;
    for (int i = 0; i < 10; i++) {
        println(val);
        val++;
        Thread.sleep(1000);
        if (val == 4) {
            System.out.println("Fun 1 在值为 4 时停止");
            throw new Exception();
        }
    }
    return val;
}

Integer fun2() throws InterruptedException {
    Integer val = 1;
    for (int i = 0; i < 10; i++) {
        println(val);
        val++;
        Thread.sleep(1000);
    }
    return val;
}

// 使用 StructuredTask API
void handle() throws ExecutionException, InterruptedException {
    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
        // 使用作用域分组
        Supplier<Integer> x = scope.fork(() -> fun1());
        Supplier<Integer> y = scope.fork(() -> fun2());
        scope.join().throwIfFailed();
    } catch (Exception e) {
        println("Fun 1 和 Fun 2 都已停止，因为 Fun 1 失败了");
    }
}

// 传统 ExecutorService 方式
void handleWithoutST() throws ExecutionException, InterruptedException {
    ExecutorService exsc = Executors.newFixedThreadPool(3);
    Future<Integer> x = exsc.submit(() -> fun1());
    Future<Integer> y = exsc.submit(() -> fun2());
    exsc.shutdown();
}
```

🔗 **相关 JEP**：[JEP 499 - 结构化任务](https://openjdk.org/jeps/499)

***

## 7. ⚡ AOT 类加载和链接：启动速度提升 40%

### 性能革命性提升

**提前（AOT）类加载和链接**旨在改善 Java 应用程序的启动时间。

👉 **实现原理**：通过在一次运行期间缓存类的加载和链接形式，并在后续运行中重用它们来实现这一点。

这一增强还为启动和预热时间的未来优化奠定了基础。

👉 **性能提升**：提前编译使 Java 程序性能提升了**40%**！

🔗 **相关 JEP**：[JEP 483 - AOT 类加载和链接](https://openjdk.org/jeps/483)

***

## 8. 🚫 告别 32 位：移除 Windows 32 位支持

### 平台支持的重要变化

JDK 24 正式移除了对 Windows 32 位系统的支持，这是 Java 平台演进的一个重要里程碑。

❌ **重要提醒**：如果你还在使用 Windows 32 位系统，必须**迁移到 64 位系统**才能使用 JDK 24 及以后的版本。

🔗 **相关 JEP**：[JEP 479 - 移除 Windows 32 位 x86 端口](https://openjdk.org/jeps/479)
