用Java反射如何实例化一个新对象,然后调用一个方法呢?

时间:2009-11-23 11:35:38

标签: java reflection

我对Java很陌生,我面临一个反思问题。

假设我必须在类fooMethod的实例上动态调用方法Foobar

到目前为止,我得到了Foobar的实例:

Object instance = Class.forName("Foobar").newInstance();

假设我知道这个对象上有fooMethod方法(我甚至可以用Class.forName("Foobar").getDeclaredMethods()来查看),请问如何调用它?

6 个答案:

答案 0 :(得分:8)

Method method = getClass().getDeclaredMethod("methodName");
m.invoke(obj);

这是在方法没有参数的情况下。如果有,则将参数类型作为参数附加到此方法。 obj是您调用方法的对象。

See the java.lang.Class docs

答案 1 :(得分:4)

纯粹反思:Method.invoke。 另一个解决方案是要求您反射创建的项目实现已知接口并强制转换为此接口并正常使用。

后者通常用于“插件”,前者不经常使用。

答案 2 :(得分:3)

您可以先阅读here

至于你之后的代码(来自同一资源):

Method[] allMethods = c.getDeclaredMethods();
    for (Method m : allMethods) {
    String mname = m.getName();
    if (!mname.startsWith("test")
        || (m.getGenericReturnType() != boolean.class)) {
        continue;
    }
    Type[] pType = m.getGenericParameterTypes();
    if ((pType.length != 1)
        || Locale.class.isAssignableFrom(pType[0].getClass())) {
        continue;
    }

    out.format("invoking %s()%n", mname);
    try {
        m.setAccessible(true);
        Object o = m.invoke(t, new Locale(args[1], args[2], args[3]));
        out.format("%s() returned %b%n", mname, (Boolean) o);

    // Handle any exceptions thrown by method to be invoked.
    } catch (InvocationTargetException x) {
        Throwable cause = x.getCause();
        err.format("invocation of %s failed: %s%n",
               mname, cause.getMessage());
    }

答案 3 :(得分:3)

您可以使用反思

示例类

package com.google.util;
Class Maths
{

public Integer doubleIt(Integer a)
{
return a*2;
}
}

并使用像这样的SomeThing -

第1步: - 将给定输入名称的类加载为String

Class<?> obj=Class.forName("Complete_ClassName_including_package");

//like:- Class obj=Class.forName("com.google.util.Maths"); 

第2步: - 获取具有给定名称和参数类型的方法

Method method=obj.getMethod("NameOfMthodToInvoke", arguments);

//arguments need to be like- java.lang.Integer.class
//like:- Method method=obj.getMethod("doubleIt",java.lang.Integer.class);

第3步: - 调用方法通过传递对象的实例和参数

Object obj2=    method.invoke(obj.newInstance(), id);
//like :- method.invoke(obj.newInstance(), 45);

你也可以做第2步

(当你 不知道特定方法存在 时,你通过循环方法的数组检查所有方法)

Method[] methods=obj.getMethods();

Method method=null;

for(int i=0;i&lt;methods.length();i++)

{

if(method[1].getName().equals("methodNameWeAreExpecting"))

{ 

method=method[i];

}

}

答案 4 :(得分:2)

这应该适合你:

((Foobar)instance).fooMethod()

答案 5 :(得分:0)

{
   "dateTime": "2020-01-22",
   "data": 1
},
{
   "dateTime": "2020-01-23",
   "data": 2
}, 
    ..

现在已弃用(https://docs.oracle.com/javase/9/docs/api/java/lang/Class.html#forName-java.lang.Module-java.lang.String-

Class.forName("Foobar").newInstance();

或者如果您需要特定的构造函数:

Class.forName("Foobar").getDeclaredConstructor().newInstance()