views:

174

answers:

6

Hi,

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?

+3  A: 

You can find an example on the Java Reflection API tutorial.

Basically you need to get the Method instance and then call "invoke" on it.

Phill Sacre
A: 

This should work for you:

((Foobar)instance).fooMethod()
quosoo
you can only do that if you knew at compile time, that instance is going to be a FooBar - which then means you wouldn't need to use reflection in the first place!
Chii
@Chii: Not necessarly. FooBar could be the most general type from which the one that you're getting through reflection is inheriting. This is how for example JDBC drivers are working and how many plugin architechtures are designed.
quosoo
+2  A: 
Method method = getClass().getDeclaredMethod("methodName");
m.invoke(obj);

This is in case the method doesn't have arguments. If it has, append the argument types as arguments to this method. obj is the object you are calling the method on.

See the java.lang.Class docs

Bozho
+2  A: 

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());
 }
Bobby
+3  A: 

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.

mlk
+1  A: 

"which then means you wouldn't need to use reflection in the first place"

Chii, that is actually quite untrue. Using interfaces and reflection is all part of building a pluggable architecture. Implementations are dynamically instantiated (usually based on property files) and methods are called based on the implementation of methods on an interface. So, quosoo's answer is perfectly valid in a pluggable architecture.

PaulP1975
Very true. However should be a comment.
quosoo
Agreed, but for some reason there was no "add comment" link. Only my posts seem to have an "add comment" link.
PaulP1975