Вызовите все методы в классе - PullRequest
2 голосов
/ 24 января 2011

У меня есть класс, в котором есть метод, который вызывает все остальные методы в том же классе.

Один из способов сделать это - использовать каркас отражения, есть ли другие способы?

[edit] Пример кода добавлен:


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

}

У меня фактически нет проблем с вызовом всех 4 методов из callAll (), т.е. избегайте использования отражения.Но один из моих коллег отметил, что, если есть 50 методов, вы будете называть их один за другим?У меня нет ответа на этот вопрос, поэтому я задаю вопрос здесь.

Спасибо, Сара

Ответы [ 4 ]

5 голосов
/ 24 января 2011

На самом деле вы, вероятно, захотите использовать 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 голос
/ 24 января 2011

Напишите метод callAll(), чтобы фактически вызывать каждый метод явно без отражения.

Это обеспечивает гибкость в создании подклассов. Это также позволяет вам иметь дело с методами, которые имеют параметры. Это также позволяет обойти методы, которые не применяются. Самое главное, что это действительно легко изменить ваш код, когда требования меняются, и это общее правило больше не применяется.

«Вызов всех методов в классе» просто не является допустимым вариантом использования. Я видел, как JUnit вызывал все методы без аргументов, начинающихся с «test» для выполнения тестовых случаев. Это самое близкое, что я сделал, и если ваша цель - сделать что-то подобное, то вы на правильном пути. Если бы вы работали над чем-то вроде этого, я не думаю, что вы бы искали альтернативы рефлексии.

1 голос
/ 24 января 2011

Я почти уверен, что все, что вы в конечном итоге делаете, все равно в конечном итоге сводится к размышлению; например: аспекты, DI и т. д. Так что я не знаю, какой будет выгода - может быть, удобство?

0 голосов
/ 05 августа 2015

Я просто подумал, что по какой-то причине я бы быстро написал способ решения этой проблемы на Java.Очевидно, что он многословен и основан на ООП.

Поскольку мы не можем использовать указатели на методы в 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...