有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何将现有的静态常量包装到枚举中?

我正在将我的Minecraft block protections插件从Bukkit移植到Sponge,这样我就可以用SpongeForge添加MOD了。Bukkit使用材质枚举来识别游戏中所有有效的块类型。我的所有保护都在配置中指定。yml文件如下:

CHEST:
  Price: 0.75
  InteractMember: R
  ...

有了enum,就可以很容易地在配置文件cost中获取keyname,并用Bukkit获取实际的enum值。getMaterial(字符串名称)。不幸的是,海绵拒绝在代码中的任何地方使用枚举,所以他们的块类型列表是一个只包含静态final int常量的类,我无法迭代或按名称检索这些常量。我试着反思

HashMap<String,Integer> blockTypes = new HashMap<String,Integer>();

for(Field field, BlockTypes.class.getFields())
    blockMap.put(field.getName(), field.getInt(null));

但我只能得到常数的int值。我需要在代码中使用常量本身,如果不为静态常量制作自己的枚举包装器,我无法找到任何方法来实现这一点:

public enum Blocks {
    ACACIA_FENCE(BlockTypes.ACACIA_FENCE),
    ACACIA_STEPS(BlockTypes.ACACIA_STEPS),
    ...
    YELLOW_FLOWER(BlockTypes.YELLOW_FLOWER);

    private final BlockTypes type;
    Blocks(BlockTypes type) {
        this.type = type;
    }
    public BlockTypes getType() { return type; }
    public static BlockTypes getByName(String name) {
        // retrieve enum by name
    }
}

我真的被困在这件事上了吗,还是我错过了另一条路


共 (1) 个答案

  1. # 1 楼答案

    海绵不使用枚举是有原因的:因为你可以添加其他mod,所以必须动态添加常量(这是不可能的),并且假设香草游戏中的块是唯一的块是无效的。支持其他mod是海绵API的主要目标之一

    如果你的目标是获得游戏中所有有效BlockType的列表,你应该使用GameRegistry

    // Getting a list of all types
    Collection<BlockType> types = Sponge.getRegistry().getAllOf(BlockType.class)
    for (BlockType type : types) {
        System.out.println(type.getName());
    }
    
    // Getting a single type by name
    Optional<BlockType> type = Sponge.getRegistry().getType(BlockType.class, "minecraft:chest");
    if (!type.isPresent()) {
        // show some error, as the given type doesn't exist
    } else {
        return type.get();
    }
    

    您应该能够使用BlockType作为映射中的键,或者使用Stringid。您不需要为它创建枚举(并且不能自动执行)

    值得注意的是,您在示例中使用反射也是错误的,但我认为现在解释如何使用反射并不重要,因为这是错误的方法