反射 - 从 HashMap 获取不同的结果 - LinkedHashMap
Reflection - Getting different results from HashMap - LinkedHashMap
我会保持简短,我有一个 Dog
class 如下所示:
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()
.
显然,它并没有缓解我的 "method call" 问题。我怎样才能克服这个问题?我必须每次都调用正确的方法。我对这种反射的东西很陌生,有什么我不应该做的,或者我做错了什么吗?或者有没有更好的方法来实现这个方法调用?
编辑:我也试过 LinkedHashMap
,但是结果是一样的。
谢谢。
getMethods()
的结果未排序,因此无法保证 method[0]
是 Foo()
(不是 Boo()
)。您需要在将其作为 "foo" 键的值映射之前进行检查。
来自 Class.getMethods()
的 javadoc:
The elements in the array returned are not sorted and are not in any particular order.
然而,您的代码假定索引 0 处的元素是方法 Foo()
。不要做这个假设。找到名称为 Foo
.
的方法
也就是说,Reflection 可能不是您正在尝试完成的工作的正确工具。你应该在更高的层次上解释你想做什么,以及为什么你认为使用反射是个好主意。通常情况下,它不是。
据我所知,这与将方法放入地图无关 - 您可以完全删除地图部分,但仍然面临同样的问题:
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()
没有按照您应该依赖的顺序 return 来自 class 的方法。如果你想专门调用你的 Foo
方法(应该是 foo
以遵循 Java 命名约定),你可能应该使用 Class.getMethod("foo")
来获取方法 按名字.
您当然也可以使用以下反射:
Dog d = new Dog();
map.put("foo", d.getClass().getMethod("Foo");
Method m = map.get("foo");
m.invoke()
此代码显然缺少所有 try catch 和其他一些东西,但它确实向您展示了重要的一点。您永远不应依赖 getMethods() 中的顺序。相反,如果您知道调用的方法是什么,请始终使用 getMethod 调用按名称获取它。这样,您一定会得到正确的方法。
我认为地图引起了一些转移注意力的问题。
Dog d = new Dog();
try {
d.getClass.getMethod("Foo").invoke(d, null);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
对此不是百分百确定,但我相信您还需要捕获 NoSuchMethodException。
我会说,除非你只是想了解反射 api,否则我会在使用反射之前三思而后行。在大多数情况下,它不是完成这项工作的正确工具。
我会保持简短,我有一个 Dog
class 如下所示:
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()
.
显然,它并没有缓解我的 "method call" 问题。我怎样才能克服这个问题?我必须每次都调用正确的方法。我对这种反射的东西很陌生,有什么我不应该做的,或者我做错了什么吗?或者有没有更好的方法来实现这个方法调用?
编辑:我也试过 LinkedHashMap
,但是结果是一样的。
谢谢。
getMethods()
的结果未排序,因此无法保证 method[0]
是 Foo()
(不是 Boo()
)。您需要在将其作为 "foo" 键的值映射之前进行检查。
来自 Class.getMethods()
的 javadoc:
The elements in the array returned are not sorted and are not in any particular order.
然而,您的代码假定索引 0 处的元素是方法 Foo()
。不要做这个假设。找到名称为 Foo
.
也就是说,Reflection 可能不是您正在尝试完成的工作的正确工具。你应该在更高的层次上解释你想做什么,以及为什么你认为使用反射是个好主意。通常情况下,它不是。
据我所知,这与将方法放入地图无关 - 您可以完全删除地图部分,但仍然面临同样的问题:
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()
没有按照您应该依赖的顺序 return 来自 class 的方法。如果你想专门调用你的 Foo
方法(应该是 foo
以遵循 Java 命名约定),你可能应该使用 Class.getMethod("foo")
来获取方法 按名字.
您当然也可以使用以下反射:
Dog d = new Dog();
map.put("foo", d.getClass().getMethod("Foo");
Method m = map.get("foo");
m.invoke()
此代码显然缺少所有 try catch 和其他一些东西,但它确实向您展示了重要的一点。您永远不应依赖 getMethods() 中的顺序。相反,如果您知道调用的方法是什么,请始终使用 getMethod 调用按名称获取它。这样,您一定会得到正确的方法。
我认为地图引起了一些转移注意力的问题。
Dog d = new Dog();
try {
d.getClass.getMethod("Foo").invoke(d, null);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
对此不是百分百确定,但我相信您还需要捕获 NoSuchMethodException。
我会说,除非你只是想了解反射 api,否则我会在使用反射之前三思而后行。在大多数情况下,它不是完成这项工作的正确工具。