如果有两个变量:

Object obj;
String methodName = "getName";

在不知道obj的类的情况下,我如何调用由methodName识别的方法?

被调用的方法没有参数,只有一个String返回值。它是Java bean的getter。


当前回答

//Step1 - Using string funClass to convert to class
String funClass = "package.myclass";
Class c = Class.forName(funClass);

//Step2 - instantiate an object of the class abov
Object o = c.newInstance();
//Prepare array of the arguments that your function accepts, lets say only one string here
Class[] paramTypes = new Class[1];
paramTypes[0]=String.class;
String methodName = "mymethod";
//Instantiate an object of type method that returns you method name
 Method m = c.getDeclaredMethod(methodName, paramTypes);
//invoke method with actual params
m.invoke(o, "testparam");

其他回答

首先,不要。避免使用这类代码。它往往是非常糟糕的代码,也不安全(请参阅安全编码指南的第6节) Java编程语言,版本2.0)。

如果你必须这样做,你更喜欢java。豆子要反射。Beans包装反射,允许相对安全和常规的访问。

索引(快)

您可以使用FunctionalInterface将方法保存在容器中以索引它们。您可以使用数组容器通过数字调用它们,或者使用hashmap通过字符串调用它们。通过这个技巧,可以为方法建立索引,从而更快地动态调用它们。

@FunctionalInterface
public interface Method {
    double execute(int number);
}

public class ShapeArea {
    private final static double PI = 3.14;

    private Method[] methods = {
        this::square,
        this::circle
    };

    private double square(int number) {
        return number * number;
    }

    private double circle(int number) {
        return PI * number * number;
    }

    public double run(int methodIndex, int number) {
        return methods[methodIndex].execute(number);
    }
}

λ语法

你也可以使用lambda语法:

public class ShapeArea {
    private final static double PI = 3.14;

    private Method[] methods = {
        number -> {
            return number * number;
        },
        number -> {
            return PI * number * number;
        },
    };

    public double run(int methodIndex, int number) {
        return methods[methodIndex].execute(number);
    }
}

编辑2022

刚才我在想为你提供一个通用的解决方案,与所有可能的方法与变量数:

@FunctionalInterface
public interface Method {
    Object execute(Object ...args);
}

public class Methods {
    private Method[] methods = {
        this::square,
        this::rectangle
    };

    private double square(int number) {
        return number * number;
    }

    private double rectangle(int width, int height) {
        return width * height;
    }

    public Method run(int methodIndex) {
        return methods[methodIndex];
    }
}

用法:

methods.run(1).execute(width, height);

对于那些在同一个类中调用非静态方法的方法,请参见下面的代码:

class Person {
    public void method1() {
        try {
            Method m2 = this.getClass().getDeclaredMethod("method2");
            m1.invoke(this);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public void method2() {
        // Do something
    }

}

Student.java

class Student{
    int rollno;
    String name;

    void m1(int x,int y){
        System.out.println("add is" +(x+y));
    }

    private void m3(String name){
        this.name=name;
        System.out.println("danger yappa:"+name);
    }
    void m4(){
        System.out.println("This is m4");
    }
}

StudentTest.java

import java.lang.reflect.Method;
public class StudentTest{

     public static void main(String[] args){

        try{

            Class cls=Student.class;

            Student s=(Student)cls.newInstance();


            String x="kichha";
            Method mm3=cls.getDeclaredMethod("m3",String.class);
            mm3.setAccessible(true);
            mm3.invoke(s,x);

            Method mm1=cls.getDeclaredMethod("m1",int.class,int.class);
            mm1.invoke(s,10,20);

        }
        catch(Exception e){
            e.printStackTrace();
        }
     }
}
Method method = someVariable.class.getMethod(SomeClass);
String status = (String) method.invoke(method);

SomeClass是类,somvariable是变量。