Вызов статического метода с использованием отражения


198

Я хочу вызвать mainметод, который является статическим. Я получил объект типа Class, но я не могу создать экземпляр этого класса, а также не могу вызвать staticметод main.

Ответы:


290
// String.class here is the parameter type, that might not be the case with you
Method method = clazz.getMethod("methodName", String.class);
Object o = method.invoke(null, "whatever");

В случае, если метод является частным использованием getDeclaredMethod()вместо getMethod(). И вызовите setAccessible(true)метод объекта.


49

От Javadoc для Method.invoke ():

Если базовый метод является статическим, то указанный аргумент obj игнорируется. Это может быть ноль.

Что происходит, когда ты

Класс класс = ...;
Метод m = klass.getDeclaredMethod (methodName, paramtypes);
m.invoke (null, args)

13
String methodName= "...";
String[] args = {};

Method[] methods = clazz.getMethods();
for (Method m : methods) {
    if (methodName.equals(m.getName())) {
        // for static methods we can use null as instance of class
        m.invoke(null, new Object[] {args});
        break;
    }
}

11
Почему бы не использовать getMethod с правильным именем вместо того, чтобы перебирать все методы?
Мьяггард

11
Иногда гораздо проще зациклить и найти метод по имени, чем использовать getMethod, потому что getMethod (или getDeclaredMethod) требует, чтобы вы тщательно проработали типы параметров. Это зависит только от того, имеет ли значение микроэффективность - итерация Java очень быстрая, поэтому если вы не вызываете метод миллионы раз в каком-то внутреннем цикле, то итерация будет достаточно быстрой
Тони Иствуд,

2
Также в более реальной ситуации вы, вероятно, найдете метод только один раз, даже если вы собираетесь использовать отражение, чтобы вызывать его несколько раз. Так что дополнительные накладные расходы при поиске не имеют значения.
RenniePet

4
Хотя у нас будет плохое время с перегруженными методами.
Ulysse Mizrahi

1
@ UlysseMizrahi все зависит от того, что вы соответствуете, но да, если вы пишете код библиотеки, может быть опасно полагаться только на имя. Я обычно проверяю конкретную аннотацию или сигнатуру конкретного метода, например «статический метод, который принимает строку и возвращает экземпляр класса», а затем утверждаю, что найден только один такой метод.
cobbzilla

0
public class Add {
    static int add(int a, int b){
        return (a+b);
    }
}

В приведенном выше примере «add» является статическим методом, который принимает два целых числа в качестве аргументов.

Следующий фрагмент кода используется для вызова метода add с входами 1 и 2.

Class myClass = Class.forName("Add");
Method method = myClass.getDeclaredMethod("add", int.class, int.class);
Object result = method.invoke(null, 1, 2);

Ссылочная ссылка .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.