有没有一种方法可以给定类名称(动态)来创建特定类的实例,并将参数传递给其构造函数。
就像是:
Object object = createInstance("mypackage.MyClass","MyAttributeValue");
"MyAttributeValue"
的构造函数的参数在哪里MyClass
?
有没有一种方法可以给定类名称(动态)来创建特定类的实例,并将参数传递给其构造函数。
就像是:
Object object = createInstance("mypackage.MyClass","MyAttributeValue");
"MyAttributeValue"
的构造函数的参数在哪里MyClass
?
Answers:
是的,类似:
Class<?> clazz = Class.forName(className);
Constructor<?> ctor = clazz.getConstructor(String.class);
Object object = ctor.newInstance(new Object[] { ctorArgument });
当然,这仅适用于单个字符串参数,但是您可以轻松地对其进行修改。
注意,类名必须是完全合格的,即包括名称空间。对于嵌套类,您需要使用美元(因为这是编译器使用的美元)。例如:
package foo;
public class Outer
{
public static class Nested {}
}
要获得该Class
对象,您需要Class.forName("foo.Outer$Nested")
。
Object[]
参数时它可能会变得棘手,因此我更喜欢在这种情况下显式创建数组。
您可以Class.forName()
用来获取Class
所需类的对象。
然后使用getConstructor()
查找所需的Constructor
对象。
最后,调用newInstance()
该对象以获取新实例。
Class<?> c = Class.forName("mypackage.MyClass");
Constructor<?> cons = c.getConstructor(String.class);
Object object = cons.newInstance("MyAttributeValue");
通过Class<?>
构造函数自变量使用Java创建对象的非常简单的方法:
情况1:-
这是此类中的一小段代码Main
:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Main {
public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// Get class name as string.
String myClassName = Base.class.getName();
// Create class of type Base.
Class<?> myClass = Class.forName(myClassName);
// Create constructor call with argument types.
Constructor<?> ctr = myClass.getConstructor(String.class);
// Finally create object of type Base and pass data to constructor.
String arg1 = "My User Data";
Object object = ctr.newInstance(new Object[] { arg1 });
// Type-cast and access the data from class Base.
Base base = (Base)object;
System.out.println(base.data);
}
}
并且,这是Base
类结构:
public class Base {
public String data = null;
public Base()
{
data = "default";
System.out.println("Base()");
}
public Base(String arg1) {
data = arg1;
System.out.println("Base("+arg1+")");
}
}
情况2:您可以为具有多个参数的构造函数类似地编写代码,并复制构造函数。例如,将3个参数作为参数传递给Base
构造函数将需要在类中创建构造函数,并且上面的代码更改如下:
Constructor<?> ctr = myClass.getConstructor(String.class, String.class, String.class);
Object object = ctr.newInstance(new Object[] { "Arg1", "Arg2", "Arg3" });
在这里,基类应该看起来像:
public class Base {
public Base(String a, String b, String c){
// This constructor need to be created in this case.
}
}
注意:- 不要忘记处理代码中需要处理的各种异常。
如果尽管遵循Singleton Pattern的类,但有人在寻找一种创建类实例的方法,则可以采用这种方法。
// Get Class instance
Class<?> clazz = Class.forName("myPackage.MyClass");
// Get the private constructor.
Constructor<?> cons = clazz.getDeclaredConstructor();
// Since it is private, make it accessible.
cons.setAccessible(true);
// Create new object.
Object obj = cons.newInstance();
这仅适用于使用私有构造函数实现单例模式的类。
您也可以在创建的对象内调用方法。
您可以通过调用第一个承包商来立即创建对象,然后在创建的对象中调用第一个方法。
Class<?> c = Class.forName("mypackage.MyClass");
Constructor<?> ctor = c.getConstructors()[0];
Object object=ctor.newInstance(new Object[]{"ContstractorArgs"});
c.getDeclaredMethods()[0].invoke(object,Object... MethodArgs);
String
作为参数?更改构造函数顺序时会变得有点凌乱
getConstructor(ClassName.class)
我猜还是更好。即使构造函数的顺序在类中发生变化,也无需手动查找位置
另一个有用的答案。如何使用getConstructor(params).newInstance(args)?
return Class.forName(**complete classname**)
.getConstructor(**here pass parameters passed in constructor**)
.newInstance(**here pass arguments**);
就我而言,我的类的构造函数将Webdriver作为参数,因此在以下代码中使用:
return Class.forName("com.page.BillablePage")
.getConstructor(WebDriver.class)
.newInstance(this.driver);
newInstance()
是varargs方法(与一样GetConstructor()
),无需显式Object
创建-array。