在不使用getDeclaredMethod的情况下接收Java方法
我希望将子类中的java方法数组初始化为类字段,如下所示在不使用getDeclaredMethod的情况下接收Java方法,java,reflection,initialization,Java,Reflection,Initialization,我希望将子类中的java方法数组初始化为类字段,如下所示 void callme() {System.out.println("hi!");} Method[] actions = new Method[] {&callme,&callme}; 并在父类处调用此数组中的所有方法,如下所示: for (meth:actions) {meth.invoke();} 但是,目前我找不到一种方法来隐式初始化actions数组,而不是通过构造函数。以下是由于未处理的异常而导致的错误:
void callme() {System.out.println("hi!");}
Method[] actions = new Method[] {&callme,&callme};
并在父类处调用此数组中的所有方法,如下所示:
for (meth:actions) {meth.invoke();}
但是,目前我找不到一种方法来隐式初始化actions数组,而不是通过构造函数。以下是由于未处理的异常而导致的错误:
Method[] actions = new Method[] {
this.getClass().getDeclaredMethod("count")
};
如上所述,在将此数组显式初始化为字段而不是构造函数时,我无法捕获异常
我是java reflection的新手,所以这可能是一个显而易见的问题,但我在google上找不到答案,任何帮助都将不胜感激
谢谢
附言
正如下面Scott所猜测的,我“希望一个超类调用子类中定义的一组特定方法”。请查看!它就像一个包裹所有反射的包装,非常容易使用。它包装了方法调用、修改属性、查找
如果您想将动态引入Java,您应该看看simple可以使用的动态JVM语言,包括一个.jar库!其中一个是包含java语法并引入大量动态功能(脚本、快速原型、元对象协议、运行时方法修复、动态代理…)。您确定反射是正确的做法吗?通常,一个带有几个匿名类的接口实现它会更好 您可以编写一个初始化程序块,以便能够在初始化期间捕获异常
为什么不使用getMethod()?在类中创建一个静态方法,该方法将返回一个声明的方法数组,并正确处理异常
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");
私有静态方法[]declaredMethods(类clazz,字符串methodName){
方法[]结果=新方法[1];
试一试{
结果[0]=clazz.getDeclaredMethod(methodName);
}捕获(NoSuchMethodException nsme){
//回应错误
}捕获(安全异常se){
//回应错误
}
返回结果;
}
方法[]行动=公布方法(“计数”);
只要您的方法是在This.getClass()中声明的,它就可以正常工作。
如果是继承的,则应改用Class.getMethod()
然而,在java中,不使用函数指针,而是使用想要调用的方法定义一个接口,并让该接口由目标对象实现
也可以考虑使用ARAYLIST或其他集合类来代替数组。
[注释:下面的代码没有被编译,但是应该跨出这个想法]
我应该回应一下——你想实现什么 如果希望超类调用子类中定义的一组特定方法,可以做几件事 对于反射,我建议使用注释: 1) 定义注释HeySuperclassCallMe(确保保留是运行时的) 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)
4) 在超类中
for (Call call : calls)
call.go();
我可以从你的符号看出你是在用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();
}
那会有用的,但这就像。。。嗯,尽管Java有时很丑陋;-)没有人能阻止您在单独的类中使用私有构造函数声明静态方法declareMethods(Class clazz,String),并隐藏所有丑陋的细节。更好的是,您可以使用一些Apache Commons库。您可以将methodName设置为varargs。您到底想做什么?正如下面Scott猜测的那样,我试图“如果您希望超类调用子类中定义的特定方法集”,我想到了注释技术,但我不喜欢它,您不能指定顺序。事实上,我最终做到了@UseMessage(order=0)。这很好,但很难看。(而且更难维护,因为无法在两者之间轻松插入方法)。顺便说一句:如果您将属性命名为“value”,则可以在不使用属性名称的情况下使用它:@UseMessage(0)。不过,这并不能帮助订购。
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();
}