How to Invoke a Java Method When Given the Method Name as a String

How do I invoke a Java method when given the method name as a string?

Coding from the hip, it would be something like:

java.lang.reflect.Method method;
try {
method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) { ... }
catch (NoSuchMethodException e) { ... }

The parameters identify the very specific method you need (if there are several overloaded available, if the method has no arguments, only give methodName).

Then you invoke that method by calling

try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) { ... }
catch (IllegalAccessException e) { ... }
catch (InvocationTargetException e) { ... }

Again, leave out the arguments in .invoke, if you don't have any. But yeah. Read about Java Reflection

How to call a method by name (String) in Java?

You cannot. Java doesn't treat functions as first class objects, because it doesn't have functional features like Python or C#.

You can create a Command interface and pass that object reference:

public interface Command {
void execute(Object [] args);
}

How to call a method from a given string in Java

This is the use-case for a switch case statement.

switch(command){
case "command1": command1(); break;
case "command2": command2(); break;

Using a string javascript style is fortunately impossible in Java. The comments links to answers how to use reflection to accomplish something similar. This is rarely a good solution.

Call a function by its name, given from string java

Java has methods, not functions. The difference is that methods have classes; you need to know the class to call the method. If it's an instance method, you need an instance to call it on, but OTOH it does mean that you can look the method up easily:

public void callByName(Object obj, String funcName) throws Exception {
// Ignoring any possible result
obj.getClass().getDeclaredMethod(funcName).invoke(obj);
}

Note that there are a lot of potential exceptions out of this and things get more complex if you want to pass arguments in.

If you are talking about a class method, what you do is slightly different:

public void callClassByName(Class cls, String funcName) throws Exception {
// Ignoring any possible result
cls.getDeclaredMethod(funcName).invoke(null);
}

You might also want to explore using a java.lang.reflect.Proxy.

How can I get a particular method name as string instead of hardcoding a method name

To find the first non-null result of a given getter of the objects in a collection, you could utilize streams, method references, and optionals, while avoiding reflection entirely.

public static <T, R> Optional<R> findFirstNonNull(Collection<T> objects, 
Function<T, R> getter) {
return objects.stream()
.filter(Objects::nonNull)
.map(getter)
.filter(Objects::nonNull)
.findFirst();
}

Example usage: Optional<String> found = findFirstNonNull(fooList, Foo::getName);

public class Foo {

private String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public static void main(String[] args) {
Foo foo1 = null;
Foo foo2 = new Foo();
Foo foo3 = new Foo();
foo3.setName("foo3");
Foo foo4 = new Foo();
foo4.setName("foo4");
List<Foo> fooList = Arrays.asList(foo1, foo2, foo3, foo4);
Optional<String> found = findFirstNonNull(fooList, Foo::getName);
System.out.println(found); // Optional[foo3]
}
}

Note: these are Java 8 features.

How to invoke a call that's given as a string value?

So I was able to create this with the link @Aditya mentioned and improvising based on my use case:

//Here key = "com.order.getItems().get(0).getId().getItemId()"
//instance = createOrder(); // instance with some values populated
public String getValue(String key, Object instance) {

String[] valuePath = key.split("\\.");
int serviceTypeIndex = 0;

if (valuePath[serviceTypeIndex].equalsIgnoreCase("com")) {
try {

Class clz = Class.forName(dataConfig.getOrder()); // FQ class name passed as string so "com.example.abc.Order" in my case
Object obj = getValueHelper(clz, instance, valuePath);
if (obj != null) {
return obj.toString();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return null;
}

private Object getValueHelper(Class<?> clazz, Object instance, String[] valuePath) {
int valuePathCounter = 2;
while (valuePathCounter < valuePath.length) {
try {
if (!methodExists(clazz, valuePath[valuePathCounter])) {
return null;
}
Method m = clazz.getMethod(valuePath[valuePathCounter]);

if (m.invoke(instance) == null) {
return null;
}
instance = m.invoke(instance);
clazz = instance.getClass();
valuePathCounter++;

} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
return null;
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return instance;
}

private boolean methodExists(Class<?> clazz, String method) {
try {
clazz.getMethod(method);
} catch (NoSuchMethodException e) {
return false;
}
return true;
}



Related Topics



Leave a reply



Submit