2

我希望在子类中初始化一个java方法数组,像这样的类字段

void callme() {System.out.println("hi!");}
Method[] actions = new Method[] {&callme,&callme};

并在父类中调用此数组中的所有方法,如下所示:

for (meth:actions) {meth.invoke();}

但是目前我找不到隐式初始化动作数组的方法,而不是通过构造函数。由于未处理的异常,以下给了我一个错误:

Method[] actions = new Method[] {
    this.getClass().getDeclaredMethod("count")
};

如前所述,当将此数组显式初始化为字段而不是在构造函数中时,我无法捕获异常。

我是 java 反射的新手,所以这可能是一个显而易见的问题,但我仍然在谷歌找不到答案,任何帮助将不胜感激。

谢谢

附言

正如下面的斯科特猜测的那样,我“想要一个超类来调用子类中定义的一组特定方法”。

4

6 回答 6

3

你确定反思是正确的做法吗?通常,具有多个实现它的匿名类的接口会更好。

您可以编写一个初始化程序块,以便能够在初始化期间捕获异常。

为什么不使用 getMethod()?

于 2009-03-13T12:58:01.637 回答
3

[注意:下面的代码尚未编译,但应该可以理解]

我应该回应——你想要完成什么?

如果您希望超类调用子类中定义的一组特定方法,您可以做一些事情。

使用反射,我建议使用注释:

1)定义一个注解HeySuperclassCallMe(确保保留是RUNTIME)

2) 用 HeySuperclassCallMe 注释要调用的方法

@HeySuperclassCallMe public void foo...

3)在你的超类中做类似的事情

for (Method m : getClass().getMethods())
  if (m.getAnnotation(HeySuperclassCallMe.class) != null)
     m.invoke(...)

这是一个很好的反思手段。

对于非反射(应该更快一点,但更多的代码):

1) 定义一个代表调用的接口

 public interface Call {
     void go();
 }

2)在你的超类中,定义一个

 private List<Call> calls
 protected void addCall(Call call)

3)在子类中,使用addCall:

 addCall(new Call() {public void go() {foo();}} );

4)在超类中

 for (Call call : calls)
    call.go();
于 2009-03-13T13:28:03.873 回答
2

查看Apache Commons - Beanutils!它就像所有反射的包装器,非常易于使用。它包装了方法调用、修改属性、查找...

如果你想为 Java 引入动态,你应该看看动态 JVM 语言,它可以通过简单的 .jar 库来使用!其中之一是Groovy,它包含 java 语法并引入了许多动态功能(脚本、快速原型设计、元对象协议、运行时方法替换、动态代理......)。

于 2009-03-13T12:57:36.490 回答
0

只要您的方法确实在 this.getClass() 中声明,这应该可以工作。如果它是继承的,你应该使用 Class.getMethod() 代替。

但是,不是使用函数指针,而是在 java 中定义一个带有要调用的方法的接口,并让该接口由目标对象实现。

还可以考虑使用 ArrayList 或其他集合类而不是数组。

于 2009-03-13T12:58:46.533 回答
0

我可以从你的 & 号看出你在用 C 语言思考。我们并没有真正使用指向 java 函数的指针。

通常,您不会为此使用 java 反射。正如其他海报之一所说 - 您将创建一个接口,并拥有实现该接口的对象 - 通过直接实现它,或者使用适配器或匿名类:

interface Callable { void callme(); }

Callable[] foo = new Callable[] {
  new Callable() { public void callme() {System.out.println("foo!");}},
  new Callable() { public void callme() {System.out.println("bar!");}}
};

for(Callable c: foo) {
  c.callme();
}
于 2009-03-13T13:32:54.300 回答
-2

在您的类中创建一个静态方法,该方法将返回一组声明的方法并正确处理异常。

private static Method[] declaredMethods(Class<T> clazz, String methodName) {
  Method[] result = new Method[1];
  try{
    result[0] = clazz.getDeclaredMethod(methodName);
  } catch (NoSuchMethodException nsme) {
    // respond to the error
  } catch (SecurityException se)  {
    // Respond to the error
  }

  return result;
}

Method[] actions = declaredMethods("count");
于 2009-03-13T12:58:23.447 回答