Java 使用其他枚举的名称调用方法
可以使用其他枚举的名称调用方法 我是用switch case语句实现的: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
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();