Vinzz
Vinzz

Reputation: 4028

With Java reflection how to instantiate a new object, then call a method on it?

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

Answers (6)

Bozho
Bozho

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.

See the java.lang.Class docs

Upvotes: 15

rob2universe
rob2universe

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

Nirbhay Mishra
Nirbhay Mishra

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

Michael Lloyd Lee mlk
Michael Lloyd Lee mlk

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

Bobby
Bobby

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

quosoo
quosoo

Reputation: 829

This should work for you:

((Foobar)instance).fooMethod()

Upvotes: 2

Related Questions