如何在接口默认方法中处理实现它的枚举遍历操作?
解决Minecraft模组中枚举+接口批量注册物品的问题
原代码的问题
- 接口里的
register()是实例方法,直接调用BasicStates.register()会编译报错,因为枚举类本身没有这个静态方法。 - 接口无法直接调用
values()——这个方法是Java编译器为枚举自动生成的专属方法,不属于任何接口,所以this.values()在接口中无法识别。
解决方案1:静态方法+泛型实现批量遍历
这种方式不需要枚举实例,直接传入枚举类即可遍历所有常量,更符合批量注册的场景:
修改后的MaterialState.java
public interface MaterialState { // 泛型限制:E必须是枚举,且实现MaterialState static <E extends Enum<E> & MaterialState> void register(Class<E> enumClass, ItemRegistryEvent event) { // 获取枚举的所有常量 for (E state : enumClass.getEnumConstants()) { // 编写物品注册逻辑,示例: ResourceLocation itemId = new ResourceLocation("你的模组ID", state.name()); Item item = new Item(new Item.Properties().tab(CreativeModeTab.TAB_MATERIALS)); event.getRegistry().register(itemId, item); } } }
BasicStates.java无需额外修改
public enum BasicStates implements MaterialState { ingot, dust, gem, ore; }
修改ItemRegistry.java的调用逻辑
@EventListener public void registerItems(ItemRegistryEvent event) { MaterialState.register(BasicStates.class, event); }
解决方案2:让枚举实现获取自身常量的方法
如果更倾向于实例方法的方式,可以让接口定义方法,强制枚举返回自身的values()数组:
修改后的MaterialState.java
public interface MaterialState { // 要求实现类返回自身的所有枚举常量 MaterialState[] getValues(); default void register(ItemRegistryEvent event) { for (MaterialState state : getValues()) { // 编写注册逻辑 ResourceLocation itemId = new ResourceLocation("你的模组ID", state.toString()); Item item = new Item(new Item.Properties().tab(CreativeModeTab.TAB_MATERIALS)); event.getRegistry().register(itemId, item); } } }
修改BasicStates.java实现getValues()
public enum BasicStates implements MaterialState { ingot, dust, gem, ore; @Override public MaterialState[] getValues() { return values(); } }
修改ItemRegistry.java的调用
@EventListener public void registerItems(ItemRegistryEvent event) { // 调用任意枚举实例的register方法即可 BasicStates.ingot.register(event); }
注意点
- 替换代码中的
你的模组ID为实际的模组ID。 - 可根据需求自定义
Item.Properties,比如设置堆叠数量、所属创造模式标签等。 - 如果需要给不同枚举常量设置不同的物品属性,可以在枚举中添加字段和方法(如
getItemProperties()),注册时调用即可。
内容的提问来源于stack exchange,提问作者Bleb1k
相关产品推荐
相关产品推荐

