Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用其他枚举的名称调用方法_Java_Reflection - Fatal编程技术网

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

Java 使用其他枚举的名称调用方法,java,reflection,Java,Reflection,可以使用其他枚举的名称调用方法 我是用switch case语句实现的: public static String getSnowmizLabel(SnowmizEnum snowmizEnum, SnowmizI18n snowmizI18n) { switch (snowmizEnum) { case MIZ1_SUBTYPE: return snowmizI18n.MIZ1_SUBTYPE(); /*100 other ca

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

我是用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反射。

我在这里看到的具体困难是,在不同的情况下需要传递不同数量的参数。您将如何推导参数

我认为您可能会发现显式地(为每种情况编写代码)进行测试以确保涵盖所有情况是最容易的

我用来编写这样的测试的模式就是我所说的“循环和切换”;我不知道有没有合适的名字。顾名思义,可以循环枚举值,然后立即切换循环变量:

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重构)也可以更轻松地工作,因为这只是简单的代码,而不是复杂的反射毛球。

使用,将命令添加到键控集合。使用枚举作为密钥有什么具体原因吗?如果不是,我会在
HashMap
中的
this.getClass().getName()
上键入每个命令

final HashMap commands=new HashMap();
final CommandA CommandA=新CommandA();
命令。放置(“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();
final HashMap commands=new HashMap();
commands.put(EnumKey.DoCommandA,newcommanda());
commands.get(EnumKey.DoCommandA.execute();

我在这里看到的具体困难是,您需要在不同的情况下传递不同数量的参数。您将如何推导参数?我想您可能会发现显式地(为每种情况编写代码)是最容易的,并通过测试确保涵盖所有情况。与其调用
snowmizI18n.MIZ1_SUBTYPE()
,不如使用
snowmizEnum.name()
和忽略参数来调用该方法。您不能忽略参数<代码>MIZ1_子类型取零<代码>MIZ2_子类型取一个。即使您反射性地调用它们,您仍然需要传递正确数量的参数。从技术上讲,使用
String
实例来确定逻辑流和手动处理类型标识是不明智的。为什么不在你的一个枚举类型中创建一个抽象方法,每个实例都会为你想要的行为覆盖它呢?谢谢你@Andy Turner,你提出的解决方案是实际的:)但是我认为写几行代码会很难看,因为有些事情可以通过反射来完成,你认为呢?
final HashMap<EnumKey, Command> commands = new HashMap<EnumKey, Command>();
commands.put(EnumKey.DoCommandA, new CommandA());
commands.get(EnumKey.DoCommandA).execute();