我会保持简短,我有一个Dog
类,如下所示:
public class Dog
{
public void Foo()
{
System.out.println("Right Call");
}
public void Boo()
{
System.out.println("Wrong Call");
}
}
以及如下的主要方法:
HashMap<String, Method> map = new HashMap<String, Method>();
Dog d = new Dog();
Method[] method = d.getClass().getMethods();
map.put("foo", method[0]);
Method a = map.get("foo");
try {
a.invoke(d, null);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}
每当我再次运行它时,它只是随意提供Right Call
或Wrong Call
输出。
我需要确保每次放置"foo"
密钥时,都必须调用Foo()
方法,而不是Boo()
。
显然,它并没有简化我的方法调用&#34;问题。我怎样才能克服这个问题?我每次都必须调用正确的方法。我对这些反思的东西很新,有什么我不应该做的,或者我做错了什么?或者有更好的方法来实现此方法调用吗?
编辑:我也试过LinkedHashMap
,但结果是一样的。
谢谢。
答案 0 :(得分:8)
来自Class.getMethods()
的javadoc:
返回的数组中的元素没有排序,也没有任何特定的顺序。
然而,您的代码假定索引0处的元素是方法Foo()
。不要做这个假设。找到名为Foo
。
那就是说,Reflection可能不是你正在尝试的工作的正确工具。您应该在更高的层次上解释您正在尝试做什么,以及为什么您认为使用反射是一个好主意。通常,它不是。
答案 1 :(得分:5)
这与将方法放在地图中无关,据我所知 - 您可以完全删除地图部分并仍然面临同样的问题:
Dog d = new Dog();
Method methods = d.getClass().getMethods();
Method a = methods[0];
try {
a.invoke(d, null);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}
从根本上说,您已经看到getMethods()
没有按照您应该依赖的顺序从类中返回方法的事实。如果您想专门调用Foo
方法(应该foo
遵循Java命名约定),您可能应该使用Class.getMethod("foo")
来获取名称的方法
答案 2 :(得分:3)
getMethods()
的结果未排序,因此无法保证method[0]
为Foo()
(不是Boo()
)。您需要先检查它,然后将其作为&#34; foo&#34;的值进行映射。键。
答案 3 :(得分:1)
您当然可以使用以下反射:
Dog d = new Dog();
map.put("foo", d.getClass().getMethod("Foo");
Method m = map.get("foo");
m.invoke()
这段代码显然缺少所有try catch和其他一些东西,但它确实显示了重要的一点。你永远不应该依赖于getMethods()中的顺序。相反,如果您知道调用该方法的方法,请始终使用getMethod调用来获取它的名称。这样,您就可以确保获得正确的方法。
答案 4 :(得分:1)
我认为地图造成了一点红鲱鱼。
Dog d = new Dog();
try {
d.getClass.getMethod("Foo").invoke(d, null);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
不是百分百肯定,但我相信你还需要捕获NoSuchMethodException。
我会说,除非你只是想了解反射api,否则在使用反射之前我会三思而后行。在大多数情况下,它不适合这项工作。