java-25-hytale
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJava 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
undefinedpowershell
undefinedUsing 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
undefinedjava --version
undefinedManual Download
手动下载
- Go to Adoptium.net
- Download Temurin 25 (LTS)
- Run installer
- Add to PATH if not automatic
- 访问 Adoptium.net
- 下载Temurin 25(LTS版本)
- 运行安装程序
- 若未自动添加,手动将其加入PATH环境变量
macOS
macOS
bash
brew install --cask temurin@25bash
brew install --cask temurin@25Linux
Linux
bash
undefinedbash
undefinedUbuntu/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
常见问题
| Issue | Solution |
|---|---|
| Wrong Java version | Set JAVA_HOME to Java 25 |
| Class not found | Check Gradle compileOnly dependency |
| Unsupported class version | Rebuild with Java 25 toolchain |
| IntelliJ uses wrong JDK | Project 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
- File → Project Structure → Project
- Set SDK to Java 25
- Set Language Level to 25
- 文件 → 项目结构 → 项目
- 将SDK设置为Java 25
- 将语言级别设置为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))
}
}