我有一个类,它有一个方法调用同一个类中的所有其余方法。
一种方法是使用反射框架,还有其他方法吗?
[编辑] 添加了示例代码:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class AClass {
private void aMethod(){
}
private void bMethod(){
}
private void cMethod(){
}
private void dMethod(){
}
//50 more methods.
//method call the rest
public void callAll() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{
Method[] methods = this.getClass().getMethods();
for (Method m : methods) {
if (m.getName().endsWith("Method")) {
//do stuff..
}
}
}
}
我实际上没有从callAll()调用所有4个方法的问题,即避免使用反射。但我的一位同事指出,如果有50种方法,你会逐一称呼它们吗?我没有答案,这就是我在这里提问的原因。
谢谢, 萨拉
答案 0 :(得分:5)
实际上,您可能想要使用Class.getDeclaredMethods()
。 Class.getMethods()
只返回公共方法,并且您显示的方法都不公开(并且它还返回从超类继承的公共方法)。
那就是说:在你提到的场景中,反思是一种有效的方法。所有其他(手动)方法都容易出错。
但是,使用命名约定对我来说似乎很弱。我会写一个自定义注释,如果存在,我会执行该方法。例如:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RunMe {}
这是您修改后的代码:
public void callAll() throws
IllegalArgumentException, IllegalAccessException, InvocationTargetException{
Method[] methods = this.getClass().getDeclaredMethods();
for (Method m : methods) {
if (m.getAnnotation(RunMe.class)!=null) {
//do stuff..
}
}
}
答案 1 :(得分:1)
我很确定你最终做的任何事情最终都会归结为反思;例如:方面,DI等。所以我不知道会有什么收获 - 方便呢?
答案 2 :(得分:1)
编写callAll()
方法以明确地实际调用每个方法而不进行反射。
这允许子类化的灵活性。它还允许您处理具有参数的方法。它还允许您绕过不适用的方法。最重要的是,当需求发生变化并且这种一揽子规则不再适用时,它可以很容易地更改代码。
“调用类上的所有方法”只是一个有效的用例。我已经看到JUnit调用所有方法,没有以“test”开头的参数来做测试用例。这是我最接近的,如果你的目标是做这样的事情,那么你就是在正确的轨道上。但是,如果你正在做这样的事情,我认为你不会寻找反思的替代方案。
答案 3 :(得分:0)
我只是因为某种原因认为我会快速编写Java方法来解决这个问题。显然它是冗长的,基于OOP。
因为我们不能在Java中使用指向方法的指针,所以我们必须创建具有方法的对象然后调用它们。你总是可以改变方法甚至采取任意数量的任意参数等。
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class AClass {
private List<Method> methods = new LinkedList<>();
methods.push( new Method()
{
private void callMethod(){
//method A
}
});
methods.push( new Method()
{
private void callMethod(){
//method B
}
});
methods.push( new Method()
{
private void callMethod(){
//method C
}
});
//50 more methods.
//method call the rest
public void callAll()
{
for (Method method : methods) {
method.callMethod();
}
}
}
public interface Method
{
void callMethod();
}