Java:如何通过字符串内容选择/调用函数?
我有一个列表和一些函数 我想迭代列表并调用与lists元素匹配的函数。 如何以比在if或switch中比较名称更优雅的方式实现这一点Java:如何通过字符串内容选择/调用函数?,java,reflection,Java,Reflection,我有一个列表和一些函数 我想迭代列表并调用与lists元素匹配的函数。 如何以比在if或switch中比较名称更优雅的方式实现这一点 class C { String [] lst = {"foo", "bar", "zoo"}; void foo () { /* ... */ } void bar () { /* ... */ } void NotSoElegant () { for (String s
class C
{
String [] lst = {"foo", "bar", "zoo"};
void foo () { /* ... */ }
void bar () { /* ... */ }
void NotSoElegant ()
{
for (String s : lst)
{
if (s.equals ("foo") == true)
{ foo (); }
if (s.equals ("bar") == true)
{ bar (); }
}
}
}
我强烈建议不要在这种情况下使用反射-这显然是代码气味,它破坏了代码的安全性,可能会导致许多问题和缺点-只要想想如果有人将
NotSoElegant
放在列表中会发生什么
当然,基本上你可以扫描类,按字符串获取方法,处理异常。。。不要这样做
基本上,拥有这样一组ifs
并没有什么坏处,但是您可以使用switch
语句对其进行重构
for (String s : lst) {
switch(s) {
case "foo":
foo();
break;
case "bar":
bar();
break;
}
}
如果您想更加可靠,并且不打破开-关规则,您应该考虑使用一些设计模式(例如),但不要使用反射:)使用Replace-Conditional-with-polymorphics重构以及lambdas/方法引用。假设您的方法不接受参数且不返回任何内容,则它们与
Runnable
接口匹配:
类{
静态最终贴图命令=Map.of(
“foo”,更优雅::foo,
“酒吧”,更优雅::酒吧,
“baz”,()->{doSomethingElse();}
);
无效执行(列表命令){
commands.forEach(c->
命令
.getOrDefault(c,()->抛出新的IllegalArgumentException(“无命令”+c))
.run()
);
}
}
你可以看看这个(可能重复):你可以创建一个Map
或Map
来避免你的if分支。@maloomeister对于这种情况,这个答案被Java 8淘汰了。Arrow-cases会使代码更易于阅读。“假设你的方法不带参数,也不返回任何东西”-和是静态的,因为你把它们放在一个静态字段中。@khelwood这种方法概括得很简单。