反射 - 从HashMap获取不同的结果 - LinkedHashMap

时间:2015-04-07 20:52:48

标签: java methods reflection hashmap linkedhashmap

我会保持简短,我有一个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 CallWrong Call输出。

我需要确保每次放置"foo"密钥时,都必须调用Foo()方法,而不是Boo()

显然,它并没有简化我的方法调用&#34;问题。我怎样才能克服这个问题?我每次都必须调用正确的方法。我对这些反思的东西很新,有什么我不应该做的,或者我做错了什么?或者有更好的方法来实现此方法调用吗?

编辑:我也试过LinkedHashMap,但结果是一样的。

谢谢。

5 个答案:

答案 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,否则在使用反射之前我会三思而后行。在大多数情况下,它不适合这项工作。