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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1782598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:36:10  来源:igfitidea点击:

With Java reflection how to instantiate a new object, then call a method on it?

javareflection

提问by Vinzz

I'm pretty new to Java, and I'm facing a reflection issue.

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

Let's say i have to dynamically call the method fooMethodon an instance of the class Foobar

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

I got so far an instance of Foobarwith:

到目前为止,我得到了一个实例Foobar

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

Let's say I know there's a method fooMethodon this object (I can even check this with Class.forName("Foobar").getDeclaredMethods()) , how to call it, please?

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

采纳答案by Bozho

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

This is in case the method doesn't have arguments. If it has, append the argument types as arguments to this method. objis the object you are calling the method on.

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

See the java.lang.Class docs

请参阅 java.lang.Class 文档

回答by quosoo

This should work for you:

这应该适合你:

((Foobar)instance).fooMethod()

回答by Bobby

You can start by reading about it here.

你可以从这里阅读它开始

As for the code you are after it is like this (from the same resource):

至于你所追求的代码是这样的(来自同一个资源):

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());
    }

回答by Michael Lloyd Lee mlk

Purely reflection: Method.invoke. The other solution is to require the item you are reflectively creating to implement a known interface and cast to this interface and use as normal.

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

The latter is commonly used for "plugins", the former is not used very often.

后者常用于“插件”,前者使用频率不高。

回答by Nirbhay Mishra

You can use reflection

你可以使用反射

sample class

样本 class

package com.google.util;
class Maths {
  public Integer doubleIt(Integer a) {
    return a*2;
  }
}

and use something like this-

并使用这样的东西 -

step 1:- Load classwith given input name as String

步骤 1:-class使用给定的输入名称加载String

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

step 2:- get Methodwith given name and parameter type

第 2 步:- 获取Method给定的名称和参数类型

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);

step 3:- invokeMethodby passing instance of Object and argument

第 3 步:-invokeMethod通过传递对象和参数的实例

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


YOU CAN DO STEP 2 LIKE THIS ALSO

你也可以这样做第 2 步

(when you do not know particular method existsin a classyou check all method by looping method's array)

(当您不知道特定方法存在于 a 中时,class您可以通过循环方法的数组来检查所有方法)

Method[] methods = obj.getMethods();

Method method = null;

for(int i=0; i < methods.length(); i++) {
  if(method[1].getName().equals("methodNameWeAreExpecting")) { 
    method = method[i];
  }
}

回答by rob2universe

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

is now deprecated (https://docs.oracle.com/javase/9/docs/api/java/lang/Class.html#forName-java.lang.Module-java.lang.String-)

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

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

or if you need a specific constructor:

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

Constructor constructor = Class.forName("java.lang.String").getConstructor(String.class);
String object = (String) constructor.newInstance("Hello");