15 枚举与注解¶
本章目标¶
- 掌握枚举:定义一组固定常量
- 掌握枚举的字段、方法、switch 配合
- 掌握常用注解
- 了解自定义注解
15.1 什么是枚举?¶
枚举(enum) 用来定义一组固定取值的常量。比如方向、颜色、生物群系、武器类型。
public enum Direction {
NORTH, SOUTH, EAST, WEST
}
// 使用
Direction dir = Direction.NORTH;
System.out.println(dir); // NORTH
对比:
// 用 int 常量(不好):容易传错、无类型检查
int NORTH = 0, SOUTH = 1;
int dir = 100; // 随便传,没人拦
// 用枚举(好):类型安全
Direction dir = Direction.NORTH; // 只能选这四个
15.2 枚举的字段与方法¶
枚举可以带字段、构造器、方法:
public enum ToolType {
SWORD("剑", 8),
PICKAXE("镐", 5),
AXE("斧", 9),
HOE("锄", 2);
private final String displayName;
private final int baseDamage;
// 构造器(private,外部不能 new)
ToolType(String displayName, int baseDamage) {
this.displayName = displayName;
this.baseDamage = baseDamage;
}
public String getDisplayName() { return displayName; }
public int getBaseDamage() { return baseDamage; }
}
// 使用
ToolType t = ToolType.SWORD;
System.out.println(t.getDisplayName()); // 剑
System.out.println(t.getBaseDamage()); // 8
15.3 枚举常用方法¶
ToolType[] all = ToolType.values(); // 所有枚举值数组
ToolType t = ToolType.valueOf("SWORD"); // 字符串转枚举(没有会抛异常)
int index = ToolType.SWORD.ordinal(); // 序号(从 0 开始),慎用
String name = ToolType.SWORD.name(); // "SWORD"
switch 配合枚举¶
switch (t) {
case SWORD -> System.out.println("近战武器");
case PICKAXE -> System.out.println("挖矿工具");
case AXE -> System.out.println("砍树工具");
default -> System.out.println("其他");
}
switch 枚举不需要写枚举名
枚举在 switch case 里直接写值(case SWORD),不用 case ToolType.SWORD。
15.4 模组里的枚举¶
// 模组常见:注册表分类
public enum ModTabs {
BUILDING("建筑方块"),
MACHINES("机器"),
TOOLS("工具武器");
private final String label;
ModTabs(String label) { this.label = label; }
public String getLabel() { return label; }
}
// Forge 里很多地方用枚举或类似模式:
// - CreativeModeTab 分组
// - 方块/物品的 Rarity(EPIC、RARE 等)
// - 游戏模式 GameType(SURVIVAL、CREATIVE...)
15.5 注解(Annotation)¶
注解是给代码打的"标签",给编译器或框架提供信息。以 @ 开头。
常用内置注解¶
@Override // 表示重写父类方法,编译器帮你检查
@Deprecated // 标记过时,调用处会有警告
@SuppressWarnings("unchecked") // 压制警告(慎用)
元注解:给注解用的注解¶
@Target(ElementType.METHOD) // 这个注解能标在哪里(方法/类/字段…)
@Retention(RetentionPolicy.RUNTIME) // 保留到什么时候(源码/字节码/运行时)
public @interface MyAnnotation {
}
@Target:作用位置(TYPE 类、FIELD 字段、METHOD 方法、PARAMETER 参数)@Retention:RUNTIME 才能被反射读取(第 19 章)
自定义注解示例¶
// 自定义注解:标记一个方法是否需要管理员权限
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequireAdmin {
boolean value() default true; // 可以带参数和默认值
}
// 使用
public class Commands {
@RequireAdmin
public void banPlayer(String name) { ... }
@RequireAdmin(false)
public void help() { ... }
}
15.6 Forge 里的注解(模组必见)¶
// Forge 模组主类注解
@Mod("ffsmod") // 声明模组 ID
public class FfsMod {
public static final String MODID = "ffsmod";
}
// 物品/方块注册(注册表对象注解)
@Mod.EventBusSubscriber(modid = FfsMod.MODID)
public class ModEvents {
@SubscribeEvent // 事件处理方法
public static void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) { ... }
@OnlyIn(Dist.CLIENT) // 仅客户端
public static void clientInit() { ... }
}
理解注解后,你就知道模组代码里那些 @Mod、@SubscribeEvent、@OnlyIn 是干什么的了——它们给 Minecraft/Forge 框架提供了"在哪里、做什么"的信息。
15.7 小练习¶
- 定义枚举
Weekday(周一到周日),每个带中文名,switch 输出"工作日/周末" - 定义枚举
Rarity(COMMON/RARE/EPIC),带颜色代码字段 - 自定义注解
@LogTime(标记方法,RUNTIME 保留),标在两个方法上
本章小结¶
- 枚举:固定取值集合,类型安全,可带字段方法
- switch + 枚举是绝配
- 注解:给代码打标签,供编译器/框架使用
- Forge 的 @Mod / @SubscribeEvent 都是注解