【问题标题】:Reflection - Getting different results from HashMap - LinkedHashMap反射 - 从 HashMap 获得不同的结果 - LinkedHashMap
【发布时间】:2015-06-12 14:40:33
【问题描述】:

我会保持简短,我有一个 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()

显然,它并不能缓解我的“方法调用”问题。我该如何克服这个问题?我必须每次都调用正确的方法。我对这些反射的东西很陌生,有什么我不应该做的,或者我做错了什么?或者有没有更好的方法来实现这个方法调用?

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

谢谢。

【问题讨论】:

标签: java methods reflection hashmap linkedhashmap


【解决方案1】:

来自Class.getMethods()的javadoc:

返回的数组中的元素没有排序,也没有任何特定的顺序。

然而,您的代码假定索引 0 处的元素是方法 Foo()。不要做这个假设。查找名称为Foo 的方法。

也就是说,Reflection 可能不是您想要完成的工作的正确工具。您应该在更高的层次上解释您正在尝试做什么以及为什么您认为使用反射是一个好主意。通常情况下,它不是。

【讨论】:

    【解决方案2】:

    据我所知,这与将方法放入地图无关 - 您可以完全删除地图部分,但仍然面临同样的问题:

    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") 来获取方法按名称

    【讨论】:

      【解决方案3】:

      getMethods() 的结果未排序,因此不能保证method[0]Foo()(不是Boo())。您需要在将其作为“foo”键的值放入地图之前对其进行检查。

      【讨论】:

        【解决方案4】:

        当然,您也可以使用以下反射:

        Dog d = new Dog();
        map.put("foo", d.getClass().getMethod("Foo");
        Method m = map.get("foo");
        m.invoke()
        

        这段代码显然缺少所有的 try catch 和其他一些东西,但它确实向您展示了重要的一点。您永远不应该依赖 getMethods() 中的顺序。相反,如果您知道调用了什么方法,请始终使用 getMethod 调用按名称获取它。这样,你一定会得到正确的方法。

        【讨论】:

          【解决方案5】:

          我认为地图引起了一些关注。

              Dog d = new Dog();
              try {
                  d.getClass.getMethod("Foo").invoke(d, null);
              } catch (IllegalAccessException | IllegalArgumentException
                      | InvocationTargetException | NoSuchMethodException e) {
                  e.printStackTrace();
              }
          

          对此不是百分百肯定,但我相信您还需要捕获 NoSuchMethodException。

          我会说,除非您只是想了解反射 api,否则在使用反射之前我会三思而后行。在大多数情况下,它不是工作的正确工具。

          【讨论】:

            猜你喜欢
            • 2016-03-26
            • 1970-01-01
            • 2015-12-21
            • 2011-03-02
            • 1970-01-01
            • 2016-06-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多