使用其他枚举的名称调用方法

时间:2017-03-04 23:11:59

标签: java reflection

可以使用其他枚举的名称来调用方法。

我用switch case语句做了这个:

public static String getSnowmizLabel(SnowmizEnum snowmizEnum, SnowmizI18n snowmizI18n) {
    switch (snowmizEnum) {
        case MIZ1_SUBTYPE:
            return snowmizI18n.MIZ1_SUBTYPE();

        /*100 other cases*/ 

        case MIZ2_SUBTYPE:
            return snowmizI18n.MIZ2_SUBTYPE(MyContext.getProjectCode());
        default:
            return snowmizEnum.name();
    }
}

但我需要使用java反射。

2 个答案:

答案 0 :(得分:0)

我在这里看到的具体困难是你需要在不同情况下传递不同数量的参数。你会如何得出参数?

我认为您可能会发现最明确地执行此操作(为每个案例编写代码),并进行测试以确保涵盖所有案例。

我用来编写这样的测试的模式就是我所谓的“循环切换”;我不知道它是否有正确的名称。顾名思义,你循环遍历枚举值,并立即切换循环变量:

for (SnowmizEnum value : SnowmizEnum.values()) {
  switch (value) {
    // ...
  }
}

这允许您为枚举中的每个值提供特定于值的检查,同时还保证您没有错过任何案例。

因此,略微填写的循环和切换测试看起来像:

for (SnowmizEnum value : SnowmizEnum.values()) {
  switch (value) {
    case MIZ1_SUBTYPE:
    case MIZ2_SUBTYPE:
    // ... + other value cases.
      // Ensure that your method works without exception in these cases.
      // Return value can be ignored, or tested if you so desire:
      // normal completion is a result in and of itself.
      getSnowmizLabel(value, snowmizI18n);
      break;

    case MIZ3_SUBTYPE:
    // ... + other value cases.
      // Ensure that your method fails for values that you expect it
      // to fail for. (You might not need this, if you expect it to
      // work in all cases)
      try {
        getSnowmizLabel(value, snowmizI18n);
        fail("Expected failure");
      } catch (SomeException expected) {}
      break;

    default:
      // Add a catch-all, so that you fail in cases you've not
      // explicitly tested.
      throw new AssertionError("Unhandled case: " + value);
  }
}

明确写出事情的明显缺点是冗长;但这是一次性费用。

这种过度反射的巨大优势在于编译器和测试确保您的代码正常运行:它可以增加或删除枚举值或更改方法的签名,因为它只会停止编译/测试将停止通过。使用语言工具(如IDE重构)也可以更轻松地工作,因为这只是简单的代码,而不是一些复杂的反射毛球。

答案 1 :(得分:0)

使用Command Pattern,将命令添加到键控集合中。您是否有使用Enum作为密钥的特定原因?如果不是,我会在this.getClass().getName() HashMap<K,V> final HashMap<String, Command> commands = new HashMap<String, Command>(); final CommandA commandA = new CommandA(); commands.put("A", commandA); commands.get("A").execute(); 上对每个命令进行键入。

final HashMap<EnumKey, Command> commands = new HashMap<EnumKey, Command>();
commands.put(EnumKey.DoCommandA, new CommandA());
commands.get(EnumKey.DoCommandA).execute();

键入Enum。

ByteBuffer icon16;
ByteBuffer icon32;
try {
    icon16 = IOUtil.ioResourceToByteBuffer("src/hexsweeper/hex16.png", 2048);
    icon32 = IOUtil.ioResourceToByteBuffer("src/hexsweeper/hex32.png", 4096);
} catch (Exception e) {
    throw new RuntimeException(e);
}


IntBuffer w = memAllocInt(1);
IntBuffer h = memAllocInt(1);
IntBuffer comp = memAllocInt(1);

try ( GLFWImage.Buffer icons = GLFWImage.malloc(2) ) {
    ByteBuffer pixels16 = stbi_load_from_memory(icon16, w, h, comp, 4);
    icons
        .position(0)
        .width(w.get(0))
        .height(h.get(0))
        .pixels(pixels16);

    ByteBuffer pixels32 = stbi_load_from_memory(icon32, w, h, comp, 4);
    icons
        .position(1)
        .width(w.get(0))
        .height(h.get(0))
        .pixels(pixels32);

    icons.position(0);
    glfwSetWindowIcon(window, icons);

    stbi_image_free(pixels32);
    stbi_image_free(pixels16);
}