How do I get a method using reflection based on a parameter value when the parameter type is an interface?
In the following case (based on this example), 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)
?
public class AbstractController {
private final AbstractModel model;
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) {}
}
private Method getMethod(Class clazz, String name, Object parameter) {
return clazz.getMethod(name, parameter.getClass());
}
}
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);
}
You can obtain the names of the formal parameters of any method or constructor with the method java. lang. reflect.
Overview. Method Parameter Reflection support was added in Java 8. Simply put, it provides support for getting the names of parameters at runtime. In this quick tutorial, we'll take a look at how to access parameter names for constructors and methods at runtime – using reflection.
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
The reflected method may be a class method or an instance method (including an abstract method). A Method permits widening conversions to occur when matching the actual parameters to invoke with the underlying method's formal parameters, but it throws an IllegalArgumentException if a narrowing conversion would occur.
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. */
If you don't mind adding a dependency to Apache Commons, you may use MethodUtils.getMatchingAccessibleMethod(Class clazz, String methodName, Class[] parameterTypes)
.
If you mind adding this dependency, you may at least find it useful to take a look at how this method is implemented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With