java-25-hytale

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Java 25 for Hytale

适用于Hytale的Java 25

Modern Java features and patterns for Hytale plugin development.
适用于Hytale插件开发的现代Java特性与模式。

Why Java 25?

为什么选择Java 25?

Hytale server runs on Java 25 - you must use this version for plugin development.
Hytale服务器运行在Java 25上——插件开发必须使用该版本。

Installation

安装

Windows (Recommended)

Windows(推荐方式)

powershell
undefined
powershell
undefined

Using winget (Windows Package Manager)

Using winget (Windows Package Manager)

winget install EclipseAdoptium.Temurin.25.JDK
winget install EclipseAdoptium.Temurin.25.JDK

Verify installation

Verify installation

java --version
undefined
java --version
undefined

Manual Download

手动下载

  1. Go to Adoptium.net
  2. Download Temurin 25 (LTS)
  3. Run installer
  4. Add to PATH if not automatic
  1. 访问 Adoptium.net
  2. 下载Temurin 25(LTS版本)
  3. 运行安装程序
  4. 若未自动添加,手动将其加入PATH环境变量

macOS

macOS

bash
brew install --cask temurin@25
bash
brew install --cask temurin@25

Linux

Linux

bash
undefined
bash
undefined

Ubuntu/Debian

Ubuntu/Debian

sudo apt install temurin-25-jdk
sudo apt install temurin-25-jdk

Fedora

Fedora

sudo dnf install temurin-25-jdk

---
sudo dnf install temurin-25-jdk

---

Key Java 25 Features for Hytale

适用于Hytale的Java 25关键特性

Records (Data Classes)

Records(数据类)

Perfect for immutable data objects:
java
// Instead of verbose class with getters/equals/hashCode
public record PlayerData(String name, int level, double health) {}

// Usage
var data = new PlayerData("Steve", 10, 100.0);
System.out.println(data.name());  // "Steve"
非常适合不可变数据对象:
java
// Instead of verbose class with getters/equals/hashCode
public record PlayerData(String name, int level, double health) {}

// Usage
var data = new PlayerData("Steve", 10, 100.0);
System.out.println(data.name());  // "Steve"

Pattern Matching

模式匹配

Cleaner type checks:
java
// Old way
if (obj instanceof Player) {
    Player player = (Player) obj;
    player.sendMessage("Hello!");
}

// Java 25 way
if (obj instanceof Player player) {
    player.sendMessage("Hello!");
}
更简洁的类型检查:
java
// Old way
if (obj instanceof Player) {
    Player player = (Player) obj;
    player.sendMessage("Hello!");
}

// Java 25 way
if (obj instanceof Player player) {
    player.sendMessage("Hello!");
}

Switch Expressions

Switch表达式

java
String message = switch (gameMode) {
    case SURVIVAL -> "Good luck surviving!";
    case CREATIVE -> "Build freely!";
    case ADVENTURE -> "Explore the world!";
    default -> "Welcome!";
};
java
String message = switch (gameMode) {
    case SURVIVAL -> "Good luck surviving!";
    case CREATIVE -> "Build freely!";
    case ADVENTURE -> "Explore the world!";
    default -> "Welcome!";
};

Pattern Matching in Switch

Switch中的模式匹配

java
Object entity = getEntity();
String type = switch (entity) {
    case Player p -> "Player: " + p.getName();
    case NPC n -> "NPC: " + n.getType();
    case Monster m -> "Monster: " + m.getName();
    case null -> "No entity";
    default -> "Unknown entity";
};
java
Object entity = getEntity();
String type = switch (entity) {
    case Player p -> "Player: " + p.getName();
    case NPC n -> "NPC: " + n.getType();
    case Monster m -> "Monster: " + m.getName();
    case null -> "No entity";
    default -> "Unknown entity";
};

Sealed Classes

密封类

Restrict inheritance:
java
public sealed class GameEvent permits PlayerEvent, WorldEvent, BlockEvent {
    // Base event class
}

public final class PlayerEvent extends GameEvent {
    // Cannot be extended further
}
限制继承:
java
public sealed class GameEvent permits PlayerEvent, WorldEvent, BlockEvent {
    // Base event class
}

public final class PlayerEvent extends GameEvent {
    // Cannot be extended further
}

Virtual Threads (Project Loom)

虚拟线程(Project Loom)

Lightweight concurrency for async operations:
java
// Old way - platform threads are heavy
new Thread(() -> loadPlayerData()).start();

// Java 25 way - virtual threads are lightweight
Thread.startVirtualThread(() -> loadPlayerData());

// Or with executor
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> loadPlayerData());
    executor.submit(() -> loadWorldData());
}
用于异步操作的轻量级并发:
java
// Old way - platform threads are heavy
new Thread(() -> loadPlayerData()).start();

// Java 25 way - virtual threads are lightweight
Thread.startVirtualThread(() -> loadPlayerData());

// Or with executor
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> loadPlayerData());
    executor.submit(() -> loadWorldData());
}

Text Blocks

文本块

Multi-line strings:
java
String json = """
    {
        "name": "MyPlugin",
        "version": "1.0.0",
        "author": "YourName"
    }
    """;

多行字符串:
java
String json = """
    {
        "name": "MyPlugin",
        "version": "1.0.0",
        "author": "YourName"
    }
    """;

Hytale-Specific Patterns

Hytale专属模式

Null Safety

空安全

Always check for null components:
java
// Good
var health = entity.getComponent(HealthComponent.class);
if (health != null) {
    health.heal(10);
}

// Better with Optional
entity.getComponentOptional(HealthComponent.class)
    .ifPresent(h -> h.heal(10));
始终检查空组件:
java
// Good
var health = entity.getComponent(HealthComponent.class);
if (health != null) {
    health.heal(10);
}

// Better with Optional
entity.getComponentOptional(HealthComponent.class)
    .ifPresent(h -> h.heal(10));

Functional Event Handling

函数式事件处理

java
// Lambda for simple handlers
registerEventListener(PlayerJoinEvent.class, 
    e -> e.getPlayer().sendMessage("Welcome!"));

// Method reference for reusable handlers
registerEventListener(PlayerJoinEvent.class, this::onPlayerJoin);

private void onPlayerJoin(PlayerJoinEvent event) {
    // Complex logic here
}
java
// Lambda for simple handlers
registerEventListener(PlayerJoinEvent.class, 
    e -> e.getPlayer().sendMessage("Welcome!"));

// Method reference for reusable handlers
registerEventListener(PlayerJoinEvent.class, this::onPlayerJoin);

private void onPlayerJoin(PlayerJoinEvent event) {
    // Complex logic here
}

Stream API for Collections

集合流API

java
// Filter and process players
List<Player> onlinePlayers = getServer().getPlayers();

onlinePlayers.stream()
    .filter(p -> p.getLevel() > 10)
    .forEach(p -> p.giveReward("veteran_badge"));

// Count specific types
long monsterCount = getWorld().getEntities().stream()
    .filter(e -> e instanceof Monster)
    .count();

java
// Filter and process players
List<Player> onlinePlayers = getServer().getPlayers();

onlinePlayers.stream()
    .filter(p -> p.getLevel() > 10)
    .forEach(p -> p.giveReward("veteran_badge"));

// Count specific types
long monsterCount = getWorld().getEntities().stream()
    .filter(e -> e instanceof Monster)
    .count();

Common Issues

常见问题

IssueSolution
Wrong Java versionSet JAVA_HOME to Java 25
Class not foundCheck Gradle compileOnly dependency
Unsupported class versionRebuild with Java 25 toolchain
IntelliJ uses wrong JDKProject Structure → SDK → Java 25

问题解决方案
Java版本错误将JAVA_HOME设置为Java 25
类未找到检查Gradle的compileOnly依赖
不支持的类版本使用Java 25工具链重新构建
IntelliJ使用错误JDK项目结构 → SDK → 选择Java 25

IDE Configuration

IDE配置

IntelliJ IDEA

IntelliJ IDEA

  1. File → Project Structure → Project
  2. Set SDK to Java 25
  3. Set Language Level to 25
  1. 文件 → 项目结构 → 项目
  2. SDK设置为Java 25
  3. 语言级别设置为25

Gradle (build.gradle.kts)

Gradle (build.gradle.kts)

kotlin
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(25))
    }
}
kotlin
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(25))
    }
}