Java - 从name和call方法创建对象

时间:2015-10-09 13:34:36

标签: java reflection

我需要编写一个Java代码,给定一个类名,创建一个该类型的对象并在其上调用一个方法。

我使用了Java.lang.Class.cast(),但是这条指令返回一个Object,并且我没有想要在Object类中运行的方法(显然)。

我发布了一些解释代码

import java.lang.reflect.*;

public class Loader {
    public static void main(String[] args) throws Exception {

        String className = "Test";
        Class[] arguments = new Class[] { int.class, int.class };
        Class klass = Class.forName(className);

        Constructor constuctor = klass.getConstructor(arguments);
        Object obj = constuctor.newInstance(new Object[] { 10, 20 });
        klass.getClass().cast(obj).Run(); // <----- PROBLEM
        // this works: ((Test)obj).Run();
    }
}

class Test {
    int a, b;
    public Test(int a1, int b1) {
        a = a1; b = b1;
    }

    public void Run() {
        System.out.println("Run...");
        System.out.println(a + " " + b);
    }
}

提前致谢。

5 个答案:

答案 0 :(得分:1)

就像您使用fullfilenames = [fullpath + '/' + fname for fname in filenames] filenameRdd = sc.parallelize(fullfilenames) allRdd2 = filenameRdd.map(lambda x: np.fromfile(x, dtype="int16", count=-1, sep='')) 获取getConstructor()对象一样,您可以使用ConstructorMethod获取getMethod()个对象。

getMethods()

另一个选择是将对象(使用常规强制转换,你永远&#34;需要使用Method m = klazz.getMethod("methodName", parameters); // Parameters optional m.invoke(obj, parameters); // Ditto )转换为已知接口并以常规方式调用它。

答案 1 :(得分:1)

通过名称和调用方法创建对象

public interface Element {
    int getId();
    String getName();
    String getFamily();
}

public class Person implements Element {
    private int Id;
    private String name;
    private String family;

    public Person() {

    }
    public Person(int id, String name, String family) {
        Id = id;
        this.name = name;
        this.family = family;
    }
    @Override
    public int getId() {
        return Id;
    }
    @Override
    public String getName() {
        return name;
    }
    @Override
    public String getFamily() {
        return family;
    }
    public void setId(int id) {
        Id = id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setFamily(String family) {
        this.family = family;
    }
}

通过名称和调用方法创建对象

public static void main(String[] args) {

    try {

        String classImportName = "database.test.Person";
        Class objClass = Class.forName(classImportName);
        Constructor constuctor = objClass.getConstructor();
        Object obj = constuctor.newInstance();


        Method callMethod = obj.getClass().getDeclaredMethod("setFamily", String.class);
        callMethod.setAccessible(true);
        callMethod.invoke(obj, "test");

        /*Field field = obj.getClass().getDeclaredField("family");
        field.setAccessible(true);
        field.set(obj,"delphani");*/

        Element elm = (Element) obj;
        System.out.println(elm.getFamily());

        //In the case the person class does not implement the 'element' Interface
        Method callMethod2 = obj.getClass().getDeclaredMethod("getFamily");
        callMethod2.setAccessible(true);
        String res = (String) callMethod2.invoke(obj);

        System.out.println("Result : " + res);

    }
    catch (Exception ex)
    {
        System.out.println(ex.getMessage());
    }
}

答案 2 :(得分:0)

使用此代替klass.getClass().cast(obj).Run();

try {
  Method method = klass.getMethod("Run");
  method.invoke(obj, new Object[0]);
} catch (Exception ex) {
  ex.printStackTrace();
}

您需要检索方法,就像对构造函数所做的那样,然后使用invoke调用该方法,并将要调用方法的Object作为第一个参数,并使用Object数组作为第二个指定传递给方法的任何参数(在您的情况下不是)。

答案 3 :(得分:0)

获得该类及其实例后,您可以尝试使用Class的此方法找到具体方法:

public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

您提供方法的名称和预期参数。如果一切顺利,您将找到它并且可以使用Method类中的此方法调用它:

public Object invoke(Object obj, Object... args)

您提供所需的实例和参数并获得结果。

答案 4 :(得分:0)

您也可以使用Object类方法,并且通过覆盖该方法,您可以访问类的常规方法,并且我们知道Object类是所有java类的超类,因此通过覆盖特定方法,您可以输入到类中

git reflog