Repository navigation
Java Interop
HimDSL 运行在 Bukkit 服务端上,所有功能都是 Java 提供的。选择器、占位符、事件都已经封装好,绝大多数情况下你用不上 Java 互操作。但有些场景例外:
HimDSL runs on a Bukkit server — everything is Java underneath. Selectors, placeholders, and events are pre-wrapped; most of the time you never need Java interop. A few cases call for it:
-
调用某个 Java 类的静态工具方法。
-
引用 Java 提供的常量(如物品、生物群系、粒子)。
-
创建 Bukkit 的对象(如
Location、ItemStack、Vector)。 -
Calling a static utility method on a Java class.
-
Referencing Java constants (items, biomes, particles).
-
Constructing Bukkit objects (
Location,ItemStack,Vector).
本章覆盖这三种场景。
This chapter covers those three cases.
用类名引用。全限定名和简单名都支持:
Reference by class name. Both fully-qualified and simple names work:
Material.DIAMOND // 简单名
org.bukkit.Material.DIAMOND // 全限定名
简单名会在常见的包里查找(org.bukkit、org.bukkit.entity、org.bukkit.event.player 等)。如果找不到,需要写全限定名:
Simple names search common packages (org.bukkit, org.bukkit.entity, org.bukkit.event.player, etc.). If not found, use the fully-qualified name:
com.example.myplugin.MyClass.CONSTANT
简单名不用写包路径,读起来更干净。日常引用 Bukkit 类型优先用简单名。
Simple names skip the package and read cleaner. Prefer them for everyday Bukkit references.
Java 类的公开静态字段可以直接读:
Read public static fields on Java classes directly:
var stone = Material.STONE;
var creative = GameMode.CREATIVE;
var diamond = Material.DIAMOND_SWORD;
读取到的值就是 Java 对象本身,可以传进方法或用于比较。
The result is the Java object itself; you can pass it to methods or compare it.
if (player.gamemode == GameMode.CREATIVE) {
runcmd("CONSOLE", "say 创造模式");
}
枚举常量就是静态字段的一种。上面 Material.STONE 和 GameMode.CREATIVE 都是枚举常量,写法与普通静态字段相同。
Enum constants are static fields. Both Material.STONE and GameMode.CREATIVE above are enum constants, written just like other static fields.
用 类名.方法名(参数) 调用静态方法:
Call static methods with ClassName.method(args):
string name = Material.DIAMOND.name();
var all = Material.values(); // 全部 Material 常量
var sword = Material.valueOf("DIAMOND_SWORD");
Material.values() 返回一个列表,可以遍历:
Material.values() returns a list you can iterate:
var mats = Material.values();
int count = mats.size();
runcmd("CONSOLE", "say Material 常量数: " + count);
调用静态方法时参数类型要匹配。HimDSL 会尝试自动转换(int → long、字符串 → 枚举),但类型实在不匹配时会报"找不到匹配的静态方法"。
Argument types must match. HimDSL auto-converts where it can (int → long, string → enum), but truly incompatible types error with "no matching static method".
new 关键字调用 Java 构造器:
The new keyword invokes a Java constructor:
var loc = new Location(world, 100.0, 64.0, 200.0);
var item = new ItemStack(Material.DIAMOND, 5);
var vec = new Vector(1.0, 0.0, 0.0);
new 接收的参数类型和个数必须与某个构造器匹配。HimDSL 会按参数尝试各构造器:
Arguments must match some constructor by type and count:
new ItemStack(Material.DIAMOND) // 单个 Material
new ItemStack(Material.DIAMOND, 5) // Material + 数量
new ItemStack(Material.DIAMOND, 5, true) // 带 metadata
参数类型不对会报"找不到匹配的构造器"。检查参数顺序和类型是最常见的调试方式。
Wrong types error with "no matching constructor". Check argument order and types first when debugging.
int main() {
var p = @p;
var world = p.getWorld();
var target = new Location(world, 100.0, 64.0, 200.0);
p.teleport(target);
runcmd("CONSOLE", "say 已传送 " + p.name);
}
p.getWorld() 和 p.teleport(...) 是通过 EntityRef 反射调用的 Java 方法。返回的 World 对象可以直接传给 new Location(...)。
p.getWorld() and p.teleport(...) go through EntityRef reflection. The returned World can be passed to new Location(...) directly.
Java 枚举常量可以两种写法:
Java enum constants support two forms:
// 通过 Java 类
var m = Material.DIAMOND;
// 通过字符串转(部分方法会这么做)
p.setGameMode("creative");
第二种依赖自动转换:方法期望枚举,HimDSL 会把字符串转成对应枚举。拼写要正确,否则报"参数类型不匹配"。
The second relies on auto-conversion: a method expecting an enum receives a string, which HimDSL converts. Spell it correctly, or "type mismatch" errors.
推荐用第一种。它是静态检查的,拼错会在引用时立刻报错。
Prefer the first form. It is statically checked; typos error immediately.
调用 Java 方法时,如果返回值是 Bukkit 的 Entity,HimDSL 会自动包成 EntityRef:
When Java methods return a Bukkit Entity, HimDSL auto-wraps it into an EntityRef:
var target = someMethodThatReturnsEntity();
// 得到的是 EntityRef,可以继续用字段式访问
string name = target.name;
double x = target.x;
这条规则让 Java 对象和 HimDSL 引用之间的衔接非常自然:大部分情况下你不需要关心底层类型是什么。
This rule makes Java and HimDSL blend smoothly: you rarely need to worry about the underlying type.
HimDSL 已经封装了大部分常见操作。能用 HimDSL 语法的,就别深入 Java:
HimDSL wraps most common operations. If a HimDSL form exists, use it:
| 需求 | 推荐写法 | 不推荐 |
|---|---|---|
| 找玩家 |
@p、@a
|
Bukkit.getOnlinePlayers() |
| 玩家属性 |
p.name、p.health
|
p.getName()、p.getHealth()
|
| 广播 | runcmd("CONSOLE", "say ...") |
Bukkit.broadcastMessage(...) |
| 发消息 | p.sendMessage(...) | runcmd(p.name, "msg ...") |
| 定时任务 | @BukkitRunnable |
Bukkit.getScheduler() |
| Need | Prefer | Avoid |
|---|---|---|
| Find players |
@p, @a
|
Bukkit.getOnlinePlayers() |
| Player fields |
p.name, p.health
|
p.getName(), p.getHealth()
|
| Broadcast | runcmd("CONSOLE", "say ...") |
Bukkit.broadcastMessage(...) |
| Send message | p.sendMessage(...) | runcmd(p.name, "msg ...") |
| Timer | @BukkitRunnable |
Bukkit.getScheduler() |
Java 互操作是"逃生舱",不是主路径。当你需要的东西 HimDSL 没有直接支持时,才动它。
Java interop is an escape hatch, not the main path. Reach for it when HimDSL has no direct form.
var x = MyRandomClass.FIELD; // ✗ 找不到类
简单名只在默认包里找。不在其中的话用全限定名:
var x = com.example.MyRandomClass.FIELD;
var item = new ItemStack(5, Material.DIAMOND); // ✗ 顺序错了
按官方文档写参数顺序。IDE 里按 Ctrl+Q(或平台对应键)可以看构造器签名。
struct Point { int x; int y; };
var p = new Point(); // ✗
结构体用 Point p;。
Simple names search only default packages. Use a fully-qualified name.
Follow the official docs for parameter order.
Structs use Point p;.
-
引用 Java 类:简单名或全限定名。
-
静态字段:
ClassName.FIELD。 -
静态方法:
ClassName.method(args)。 -
构造对象:
new ClassName(args)。 -
返回值是
Entity时自动包成EntityRef。 -
HimDSL 已有封装的操作优先用封装,Java 互操作是兜底。
-
Refer to Java classes by simple or fully-qualified name.
-
Static fields:
ClassName.FIELD. -
Static methods:
ClassName.method(args). -
Construct objects:
new ClassName(args). -
Returned
Entityis auto-wrapped intoEntityRef. -
Prefer HimDSL's own forms; interop is a fallback.
自定义类型部分到此结束。四章覆盖了:结构体定义与字段、结构体方法、用户枚举、Java 互操作。
The Custom Types section ends here. Four chapters covered: struct definition and fields, struct methods, user enums, and Java interop.
选择原则:
Decision guide:
-
一组相关数据 →
struct。 -
有限固定取值 →
enum。 -
与外部 Java 交互 → Java 互操作,但只在 HimDSL 没封装时使用。
-
A group of related values →
struct. -
A finite fixed set →
enum. -
Interop with external Java → interop, but only when HimDSL has no wrapped form.
默认用基本类型和容器,只有明确需要时才定义结构体或枚举。不要为了"看起来专业"而给简单数据加包装。
Default to primitives and containers; define structs or enums only when clearly needed. Do not add wrappers for simple data just to look professional.
下一部分进入 Minecraft 集成。第十章 [选择器总览 / Selectors-Overview] 系统讲解选择器的所有形式与过滤规则。
The next part covers Minecraft Integration. Chapter [选择器总览 / Selectors-Overview] walks through all selector forms and filter rules.
- 首页 / Home
- 安装与快速开始 / Installation & Quick Start
- 第一个脚本 / Your First Script
- 命令速查 / Command Reference
- 自动执行脚本 / Auto-run Scripts
- 定义函数 / Defining Functions
- 函数重载 / Function Overloading
- Lambda 表达式 / Lambda Expressions
- 函数式接口 / Functional Interfaces
- 选择器总览 / Selectors Overview
- 选择器过滤器 / Selector Filters
- EntityRef 引用 / EntityRef
- 占位符参考 / Placeholders Reference
- PlaceholderAPI 桥接 / PAPI Bridge
- 创建 GUI / Creating a GUI
- GUISlot 槽位 / GUISlot
- 点击回调 / Click Callbacks
- onClose 回调 / onClose Callback
- GUI 刷新 / GUI Refresh
- 数学函数 / Math Built-ins
- 高精度计算 / BigDecimal Built-ins
- 字符串函数 / String Built-ins
- 集合函数 / Collection Built-ins
- 文件 I/O / File I/O
- 命令与 sleep / Commands & sleep