Java 引用同一方法时的反射 NoSuchMethodException class
Java Reflection NoSuchMethodException when referencing a method in same class
当我尝试在同一个 class 中的方法上调用 getMethod 时遇到了 NoSuchMethodException,并且没有来自哈希映射中提取的字符串名称的参数。任何建议,或另一种在同一个 class 中调用方法的方法,只给出方法的字符串名称?
获取方法的调用在这里:
if (testChoices.containsKey(K)) {
String method = testChoices.get(K);
System.out.println(method);
try {
java.lang.reflect.Method m = TST.getClass().getMethod(method);
m.invoke(testChoices.getClass());
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
System.out.println("No method found");
e1.printStackTrace();
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
我尝试调用的方法之一在这里:
private static void testgetDomainLic() throws IOException {
被调用的地图入口在这里:
testChoices.put(1, "testgetDomainLic");
我不是专家,但请尝试更改您的方法,使其不是私有的。
私有方法可以通过反射调用,但是需要额外的步骤。参见 Any way to Invoke a private method?
我认为在你的情况下你可以改变 getMethod
to getDeclaredMethod
。 getMethod
只有 return 种 public 方法。
这里的小问题是它们实际上 other 与它们是否 return 非 public 方法具有不同的语义。 getDeclaredMethod
仅包括 声明的 而非 继承的 的方法。
例如:
class Foo { protected void m() {} }
class Bar extends Foo {}
Foo actuallyBar = new Bar();
// This will throw NoSuchMethodException
// because m() is declared by Foo, not Bar:
actuallyBar.getClass().getDeclaredMethod("m");
在最坏的情况下,你必须遍历所有声明的方法,像这样:
Class<?> c = obj.getClass();
do {
for (Method m : c.getDeclaredMethods())
if (isAMatch(m))
return m;
} while ((c = c.getSuperclass()) != null);
或者考虑接口(主要是因为他们现在可以声明静态方法):
List<Class<?>> classes = new ArrayList<>();
for (Class<?> c = obj.getClass(); c != null; c = c.getSuperclass())
classes.add(c);
Collections.addAll(classes, obj.getClass().getInterfaces());
Method m = classes.stream()
.map(Class::getDeclaredMethods)
.flatMap(Arrays::stream)
.filter(this::isAMatch)
.findFirst()
.orElse(null);
附带说明一下,您可能 不需要 调用 m.setAccessible(true)
,因为您是从 class 中调用它的声明它。不过,在其他情况下这是必要的。
当我尝试在同一个 class 中的方法上调用 getMethod 时遇到了 NoSuchMethodException,并且没有来自哈希映射中提取的字符串名称的参数。任何建议,或另一种在同一个 class 中调用方法的方法,只给出方法的字符串名称? 获取方法的调用在这里:
if (testChoices.containsKey(K)) {
String method = testChoices.get(K);
System.out.println(method);
try {
java.lang.reflect.Method m = TST.getClass().getMethod(method);
m.invoke(testChoices.getClass());
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
System.out.println("No method found");
e1.printStackTrace();
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
我尝试调用的方法之一在这里:
private static void testgetDomainLic() throws IOException {
被调用的地图入口在这里:
testChoices.put(1, "testgetDomainLic");
我不是专家,但请尝试更改您的方法,使其不是私有的。
私有方法可以通过反射调用,但是需要额外的步骤。参见 Any way to Invoke a private method?
我认为在你的情况下你可以改变 getMethod
to getDeclaredMethod
。 getMethod
只有 return 种 public 方法。
这里的小问题是它们实际上 other 与它们是否 return 非 public 方法具有不同的语义。 getDeclaredMethod
仅包括 声明的 而非 继承的 的方法。
例如:
class Foo { protected void m() {} }
class Bar extends Foo {}
Foo actuallyBar = new Bar();
// This will throw NoSuchMethodException
// because m() is declared by Foo, not Bar:
actuallyBar.getClass().getDeclaredMethod("m");
在最坏的情况下,你必须遍历所有声明的方法,像这样:
Class<?> c = obj.getClass();
do {
for (Method m : c.getDeclaredMethods())
if (isAMatch(m))
return m;
} while ((c = c.getSuperclass()) != null);
或者考虑接口(主要是因为他们现在可以声明静态方法):
List<Class<?>> classes = new ArrayList<>();
for (Class<?> c = obj.getClass(); c != null; c = c.getSuperclass())
classes.add(c);
Collections.addAll(classes, obj.getClass().getInterfaces());
Method m = classes.stream()
.map(Class::getDeclaredMethods)
.flatMap(Arrays::stream)
.filter(this::isAMatch)
.findFirst()
.orElse(null);
附带说明一下,您可能 不需要 调用 m.setAccessible(true)
,因为您是从 class 中调用它的声明它。不过,在其他情况下这是必要的。