在Java中使用字符串调用方法

时间:2018-04-01 06:24:42

标签: java

如何在Java中使用String调用方法。例如,

    String a = "call";
    int b = a();

    private static int call() {
         return 1;
    }

我知道它与反射有关,但我不知道如何让它发挥作用。

2 个答案:

答案 0 :(得分:0)

可以使用反射执行此操作。首先获取Class的引用,使用它来获取Method的名字。然后你可以调用那个方法。例如,

public class Test {    
    public static int call() {
        return 42;
    }

    public static void main(String[] args) throws Exception {
        Method m = Test.class.getMethod("call", new Class[0]);
        Object o = m.invoke(null, new Object[0]);
        System.out.println(o);
    }
}

输出生命,宇宙和一切的意义。

答案 1 :(得分:0)

反射。或方法句柄。

反射:

 import java.lang.Reflect;

 public class SomeClass {
     public void someMethod() {
         String a = "call";

         try {
             Method m = SomeClass.class.getDeclaredMethod(a);
             m.setAccessible(true);
             m.invoke(null);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
    }
}

没有反射,使用MethodHandles:

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public class Example {
    public static void main(String[] args) {
        String a = "call";
        try {
            MethodHandle h = MethodHandles.lookup()
                .findStatic(Example.class, a, MethodType.methodType(Integer.TYPE));
            int result = (int) h.invokeExact();
            System.out.println(result);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }

    @SuppressWarnings("unused")
    private static int call() {
        return 42;
    }
}

MethodHandles据说速度更快,但它们还有一些额外的限制,比如你只能使用它们来调用你可以在当前上下文中调用的代码。

在这种情况下,此限制适用于我们,因为call是私有的,因此我们可以调用它。但是如果我们尝试从不同的类中做到这一点,我们将得到一个例外。 (我们可以传递lookup()findStatic()的结果,其他人也可以为我们调用。)

此外,如果存在SecurityManager,则MethodHandles示例有效。