Call all methods within a class
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
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..
}
}
}
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?
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.
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();
}
精彩评论