Reputation: 4028
I'm pretty new to Java, and I'm facing a reflection issue.
Let's say i have to dynamically call the method fooMethod
on an instance of the class Foobar
I got so far an instance of Foobar
with:
Object instance = Class.forName("Foobar").newInstance();
Let's say I know there's a method fooMethod
on this object (I can even check this with Class.forName("Foobar").getDeclaredMethods()
) , how to call it, please?
Upvotes: 30
Views: 68618
Reputation: 597076
Method method = getClass().getDeclaredMethod("methodName");
method.invoke(obj);
This is in case the method doesn't have arguments. If it does, append the argument types as arguments to this method.
obj
is the object you are calling the method on.
Upvotes: 15
Reputation: 7583
Class.forName("Foobar").newInstance();
is now deprecated (https://docs.oracle.com/javase/9/docs/api/java/lang/Class.html#forName-java.lang.Module-java.lang.String-)
Class.forName("Foobar").getDeclaredConstructor().newInstance()
or if you need a specific constructor:
Constructor constructor = Class.forName("java.lang.String").getConstructor(String.class);
String object = (String) constructor.newInstance("Hello");
Upvotes: 1
Reputation: 1648
You can use reflection
sample class
package com.google.util;
class Maths {
public Integer doubleIt(Integer a) {
return a*2;
}
}
and use something like this-
step 1:- Load class
with given input name as String
Class<?> obj = Class.forName("Complete_ClassName_including_package");
//like:- Class obj = Class.forName("com.google.util.Maths");
step 2:- get Method
with given name and parameter type
Method method = obj.getMethod("NameOfMthodToInvoke", arguments);
//arguments need to be like- `java.lang.Integer.class`
//like:- Method method= obj.getMethod("doubleIt", java.lang.Integer.class);
step 3:- invoke
Method
by passing instance of Object and argument
Object obj2 = method.invoke(obj.newInstance(), id);
//like :- method.invoke(obj.newInstance(), 45);
YOU CAN DO STEP 2 LIKE THIS ALSO
(when you do not know particular method exists in a class
you check all method by looping method's array)
Method[] methods = obj.getMethods();
Method method = null;
for(int i=0; i < methods.length(); i++) {
if(method[1].getName().equals("methodNameWeAreExpecting")) {
method = method[i];
}
}
Upvotes: 7
Reputation: 14661
Purely reflection: Method.invoke. The other solution is to require the item you are reflectively creating to implement a known interface and cast to this interface and use as normal.
The latter is commonly used for "plugins", the former is not used very often.
Upvotes: 5
Reputation: 1611
You can start by reading about it here.
As for the code you are after it is like this (from the same resource):
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();
if (!mname.startsWith("test")
|| (m.getGenericReturnType() != boolean.class)) {
continue;
}
Type[] pType = m.getGenericParameterTypes();
if ((pType.length != 1)
|| Locale.class.isAssignableFrom(pType[0].getClass())) {
continue;
}
out.format("invoking %s()%n", mname);
try {
m.setAccessible(true);
Object o = m.invoke(t, new Locale(args[1], args[2], args[3]));
out.format("%s() returned %b%n", mname, (Boolean) o);
// Handle any exceptions thrown by method to be invoked.
} catch (InvocationTargetException x) {
Throwable cause = x.getCause();
err.format("invocation of %s failed: %s%n",
mname, cause.getMessage());
}
Upvotes: 3