views:

40

answers:

1

Maybe I'm missing something simple here but how do I get a method whose parameter is an interface using reflection.

In the following case newValue would be a List<String> called foo. So I would call addModelProperty("Bar", foo); But this only works for me if I don't use the interface and only use LinkedList<String> foo. How do I use an interface for newValue and get the method from model that has an interface as the parameter addBar(List<String> a0)?

Here is a more detailed example. (based on: This example)

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);
}
+4  A: 

You'll actually have to search through all the methods in your model and find those that are compatible with the arguments you have. It is a bit messy, because, in general, there might be more that one.

If you are interested in just public methods, the getMethods() method is the easiest to use, because it gives you all accessible methods without walking the class hierarchy.

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. */
erickson