Используя отражение, чтобы получить метод; параметры метода типов интерфейса не найдены - PullRequest
3 голосов
/ 30 августа 2010

Может быть, я упускаю что-то простое здесь, но как мне получить метод, параметр которого является интерфейсом, использующим отражение.

В следующем случае newValue будет List<String> с именем foo. Поэтому я бы назвал addModelProperty("Bar", foo); Но это работает только для меня, если я не использую интерфейс и использую только LinkedList<String> foo. Как использовать интерфейс для newValue и получить метод от model, у которого в качестве параметра addBar(List<String> a0)?

имеется интерфейс

Вот более подробный пример. (на основе: Этот пример )

public class AbstractController {
  public setModel(AbstractModel model) {
    this.model = model;
  }
  protected void addModelProperty(String propertyName, Object newValue) {
    try {
      Method method = getMethod(model.getClass(), "add" + propertyName, newValue);
      method.invoke(model, newValue);
    } catch (NoSuchMethodException e) {
    } catch (InvocationTargetException e) {
    } catch (Exception e) {}
    }
}

public class AbstractModel {
  protected PropertyChangeSupport propertyChangeSupport;
  protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
    propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
  }
}

public class Model extends AbstractModel {
  public void addList(List<String> list) {
    this.list.addAll(list);
  }
}

public class Controller extends AbstractController {
  public void addList(List<String> list) {
    addModelProperty(list);
  }
}

public void example() {
  Model model = new Model();
  Controller controller = new Controller();
  List<String> list = new LinkedList<String>();
  list.add("example");
// addList in the model is only found if LinkedList is used everywhere instead of List
  controller.addList(list);
}

Ответы [ 2 ]

11 голосов
/ 30 августа 2010

На самом деле вам придется искать все методы в вашей модели и находить те, которые совместимы с вашими аргументами.Это немного грязно, потому что, как правило, их может быть больше.

Если вас интересуют только публичные методы, метод getMethods() проще всего использовать, поскольку он предоставляет вам всеметоды без обхода иерархии классов.

Collection<Method> candidates = new ArrayList<Method>();
String target = "add" + propertyName;
for (Method m : model.getClass().getMethods()) {
  if (target.equals(m.getName())) {
    Class<?>[] params = m.getParameterTypes();
    if (params.length == 1) {
      if (params[0].isInstance(newValue))
        candidates.add(m);
    }
  }
}
/* Now see how many matches you have... if there's exactly one, use it. */
6 голосов
/ 25 сентября 2012

Если вы не возражаете против добавления зависимости в Apache Commons, вы можете использовать MethodUtils.getMatchingAccessibleMethod(Class clazz, String methodName, Class[] parameterTypes).

Если вы не возражаете против добавления этой зависимости, вы можете по крайней мере найти ее полезной дляпосмотрите , как реализован этот метод .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...