Call all methods within a class

我是研究僧i 提交于 2020-01-14 14:10:03

问题


I have a class, which has a method calls all of the rest methods within the same class.

One way to do it is by using reflection framework, are there other ways?

[edit] Example code added:


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..
            }
        }
    }

}

I actually don't have a problem with calling all 4 methods from callAll(), i.e. avoid using reflection. But one of my colleagues pointed out that what if there are 50 methods, are you going to call them one by one? I don't have an answer for that, that's why I am asking the question here.

Thanks, Sarah


回答1:


I'm pretty sure that anything you end up doing is going to ultimately boil down to reflection anyways; eg: aspects, DI, etc. So I don't know what the gain would be - convenience maybe?




回答2:


Actually, you'd probably want to use Class.getDeclaredMethods(). Class.getMethods() only returns public methods and none of the methods you show are public (and it also returns the public methods inherited from super classes).

That said: In the scenario you mention, reflection is a valid approach. All other (manual) approaches would be error-prone.

However, using a naming convention seems to weak to me as a guard. I'd write a custom annotation, and if that is present, I'd execute the method. Example:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RunMe {}

And here's your modified code:

public void callAll() throws
IllegalArgumentException, IllegalAccessException, InvocationTargetException{
    Method[] methods = this.getClass().getDeclaredMethods();
    for (Method m : methods) {
        if (m.getAnnotation(RunMe.class)!=null) {
            //do stuff..
        }
    }
}



回答3:


Write the callAll() method to actually call each method explicitly without reflection.

This allows for flexibility in subclassing. It also allows you to deal with methods which have parameters. It also allows you to bypass methods which don't apply. Most importantly, it makes it really easy to change your code when requirements change and this blanket rule no longer applies.

"Calling all methods on a class" is just not a valid use-case. I've seen JUnit call all methods without arguments beginning with "test" to do test cases. That's about the closest I've come, and if your goal is to do something like this, then you are on the right track. If you were working on something like this, though, I don't think you'd be looking for alternatives to reflection.




回答4:


I just thought for some reason I'd quickly write the Java way of approaching this problem. Obviously it's verbose and OOP based.

Because we can't use pointers to methods in Java, we have to make Objects that have methods and then call them. You could always change the method even to take arbitrary amounts of arbitrary arguments etc.

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();
}


来源:https://stackoverflow.com/questions/4778238/call-all-methods-within-a-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!