使用类名称和调用构造函数创建一个实例
有没有办法创建一个特定类的实例给定的类名(动态),并传递给它的构造函数的参数。
就像是:
Object object = createInstance("mypackage.MyClass","MyAttributeValue");
其中"MyAttributeValue"
是MyClass
的构造函数的参数。
是的,像这样的:
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")
。
您可以使用Class.forName()
来获取所需类的Class
对象。
然后使用getConstructor()
来找到所需的Constructor
对象。
最后,在该对象上调用newInstance()
以获取新实例。
Class<?> c = Class.forName("mypackage.MyClass"); Constructor<?> cons = c.getConstructor(String.class); Object object = cons.newInstance("MyAttributeValue");
你可以使用反射
return Class.forName(className).getConstructor(String.class).newInstance(arg);
如果类只有一个空的构造函数(如Activity或Fragment等,Android类):
Class<?> myClass = Class.forName("com.example.MyClass"); Constructor<?> constructor = myClass.getConstructors()[0];
当使用(即) getConstructor(String.lang)
,构造函数必须声明为public。 否则会引发NoSuchMethodException
。
如果你想访问一个非公共的构造函数,你必须改用(即) getDeclaredConstructor(String.lang)
。
你想要使用java.lang.reflect.Constructor.newInstance(Object …)
使用带构造函数参数的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. } }
注意: – 不要忘记处理代码中需要处理的各种异常。
您也可以调用创建的对象中的方法。
您可以通过调用第一个约束器立即创建对象,然后调用创建的对象中的第一个方法。
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);
如果有人正在寻找一种方法来创建一个类的实例,尽管类Singleton模式下面,这是一个方法来做到这一点。
// 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();
这只适用于使用私有构造函数实现单例模式的类。
另一个有用的答案 我如何使用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);