Вопрос-ответ

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

Как мне вызвать метод Java, если имя метода задано в виде строки?

Если у меня есть две переменные:

Object obj;
String methodName = "getName";

Не зная класса obj, как я могу вызвать в нем метод, идентифицированный с помощью methodName?

Вызываемый метод не имеет параметров и String возвращает значение. Это средство получения для Java bean.

Переведено автоматически
Ответ 1

Кодирование с нуля, это было бы что-то вроде:

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

Параметры определяют очень конкретный метод, который вам нужен (если доступно несколько перегруженных методов, если у метода нет аргументов, только укажите methodName).

Затем вы вызываете этот метод, вызывая

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

Опять же, не указывайте аргументы в .invoke, если у вас их нет. Но да. Почитайте о отражении Java

Ответ 2

Используйте вызов метода из отражения:

Class<?> c = Class.forName("class name");
Method method = c.getDeclaredMethod("method name", parameterTypes);
method.invoke(objectToInvokeOn, params);

Где:


  • "class name" это имя класса

  • objectToInvokeOn имеет тип Object и является объектом, на котором вы хотите вызвать метод

  • "method name" это имя метода, который вы хотите вызвать

  • parameterTypes имеет тип Class[] и объявляет параметры, которые принимает метод

  • params имеет тип Object[] и объявляет параметры, которые должны быть переданы методу

Ответ 3

Для тех, кому нужен простой пример кода на Java 7:

Dog класс:

package com.mypackage.bean;

public class Dog {
private String name;
private int age;

public Dog() {
// empty constructor
}

public Dog(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

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

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public void printDog(String name, int age) {
System.out.println(name + " is " + age + " year(s) old.");
}
}

ReflectionDemo класс:

package com.mypackage.demo;

import java.lang.reflect.*;

public class ReflectionDemo {

public static void main(String[] args) throws Exception {
String dogClassName = "com.mypackage.bean.Dog";
Class<?> dogClass = Class.forName(dogClassName); // convert string classname to class
Object dog = dogClass.newInstance(); // invoke empty constructor

String methodName = "";

// with single parameter, return void
methodName = "setName";
Method setNameMethod = dog.getClass().getMethod(methodName, String.class);
setNameMethod.invoke(dog, "Mishka"); // pass arg

// without parameters, return string
methodName = "getName";
Method getNameMethod = dog.getClass().getMethod(methodName);
String name = (String) getNameMethod.invoke(dog); // explicit cast

// with multiple parameters
methodName = "printDog";
Class<?>[] paramTypes = {String.class, int.class};
Method printDogMethod = dog.getClass().getMethod(methodName, paramTypes);
printDogMethod.invoke(dog, name, 3); // pass args
}
}

Вывод:
Mishka is 3 year(s) old.


Вы можете вызвать конструктор с параметрами таким образом:

Constructor<?> dogConstructor = dogClass.getConstructor(String.class, int.class);
Object dog = dogConstructor.newInstance("Hachiko", 10);

В качестве альтернативы вы можете удалить

String dogClassName = "com.mypackage.bean.Dog";
Class<?> dogClass = Class.forName(dogClassName);
Object dog = dogClass.newInstance();

и выполнить

Dog dog = new Dog();

Method method = Dog.class.getMethod(methodName, ...);
method.invoke(dog, ...);

Рекомендуемое чтение: Создание новых экземпляров класса

Ответ 4

Метод может быть вызван следующим образом. Есть и другие возможности (проверьте reflection api), но это самая простая из них:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Assert;
import org.junit.Test;

public class ReflectionTest {

private String methodName = "length";
private String valueObject = "Some object";

@Test
public void testGetMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
Method m = valueObject.getClass().getMethod(methodName, new Class[] {});
Object ret = m.invoke(valueObject, new Object[] {});
Assert.assertEquals(11, ret);
}



}
java reflection