Minecraft模组开发:能否用[]替代点号调用子类?
动态访问Minecraft模组中的物品实例:可行方案
完全可行,这在Minecraft模组开发常用的Java(或Kotlin)环境中属于动态访问对象属性的场景,下面给你两种简单直接的实现方案:
方案1:手动维护映射表(推荐,封装性好)
在你的ModItems类里新增一个静态映射集合,注册物品时同步存入名称与实例的对应关系:
public class ModItems { // 你的物品实例 public static final Item ROCK = registerItem("rock", new Item(new Item.Properties())); public static final Item IRON_INGOT = registerItem("iron_ingot", new Item(new Item.Properties())); // 存储名称到物品实例的映射 private static final Map<String, Item> ITEM_NAME_MAP = new HashMap<>(); private static Item registerItem(String name, Item item) { // 存入映射表 ITEM_NAME_MAP.put(name, item); // 这里加入你原本的物品注册逻辑(比如Forge/Fabric的注册代码) return item; } // 对外提供通过名称获取物品的方法 public static Item getItemByName(String itemName) { return ITEM_NAME_MAP.get(itemName); } }
之后就能按你想要的逻辑调用:
ModItems.getItemByName(itemName).get();
方案2:利用反射(快捷但需谨慎)
如果不想手动维护映射表,可以用Java反射直接读取ModItems中的静态物品字段:
public class ModItems { public static final Item ROCK = ...; public static final Item IRON_INGOT = ...; public static Item getItemByName(String itemName) { try { // 注意字段名要和传入的字符串匹配,比如"rock"对应字段ROCK需转大写,或保持字段名小写 Field field = ModItems.class.getField(itemName.toUpperCase()); return (Item) field.get(null); } catch (NoSuchFieldException | IllegalAccessException e) { // 处理物品不存在的情况,比如返回null或抛出自定义异常 e.printStackTrace(); return null; } } }
调用方式和方案1一致:ModItems.getItemByName(itemName).get();
额外提醒
- 如果你用的是Forge/Fabric的注册系统(比如
RegistryObject<Item>),记得要调用.get()拿到实际的物品实例,而非注册对象本身 - 反射方案虽然快捷,但性能略低于手动映射,且字段名与字符串不匹配时容易出错,适合小项目或快速测试场景
- 若用Kotlin开发,语法会更简洁,可直接通过
ModItems::class.members遍历属性,或定义val itemMap = mapOf("rock" to ROCK, ...)实现映射
内容的提问来源于stack exchange,提问作者Danonek 07
相关产品推荐
相关产品推荐

