Java 使用类名和调用构造函数创建实例
是否有方法在给定类名(动态)的情况下创建特定类的实例,并将参数传递给其构造函数 比如:Java 使用类名和调用构造函数创建实例,java,reflection,instantiation,Java,Reflection,Instantiation,是否有方法在给定类名(动态)的情况下创建特定类的实例,并将参数传递给其构造函数 比如: Object object = createInstance("mypackage.MyClass","MyAttributeValue"); Class<?> clazz = Class.forName(className); Constructor<?> ctor = clazz.getConstructor(String.class); Object object = ctor
Object object = createInstance("mypackage.MyClass","MyAttributeValue");
Class<?> clazz = Class.forName(className);
Constructor<?> ctor = clazz.getConstructor(String.class);
Object object = ctor.newInstance(new Object[] { ctorArgument });
其中,“MyAttributeValue”
是MyClass
的构造函数的参数,您可以使用它来获取所需类的对象
然后使用查找所需对象
最后,调用该对象以获取新实例
Class<?> c = Class.forName("mypackage.MyClass");
Constructor<?> cons = c.getConstructor(String.class);
Object object = cons.newInstance("MyAttributeValue");
Class c=Class.forName(“mypackage.MyClass”);
构造函数cons=c.getConstructor(String.class);
Object Object=cons.newInstance(“MyAttributeValue”);
是的,类似于:
Object object = createInstance("mypackage.MyClass","MyAttributeValue");
Class<?> clazz = Class.forName(className);
Constructor<?> ctor = clazz.getConstructor(String.class);
Object object = ctor.newInstance(new Object[] { ctorArgument });
要获取该对象的
Class
对象,您需要Class.forName(“foo.Outer$Nested”)
您可以使用反射
return Class.forName(className).getConstructor(String.class).newInstance(arg);
如果类只有一个空构造函数(如Activity或Fragment等,android类),则需要使用:
Class myClass=Class.forName(“com.example.myClass”);
构造函数=myClass.getConstructors()[0];
当使用(即getConstructor(String.lang)
构造函数必须声明为公共的。
否则将抛出NoSuchMethodException
如果您想访问一个非公共构造函数,则必须改用(即
getDeclaredConstructor(String.lang)
,您还可以在创建的对象内调用方法
您可以通过调用第一个constractor,然后调用所创建对象中的第一个方法来创建即时对象
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);
Class c=Class.forName(“mypackage.MyClass”);
构造函数ctor=c.getConstructors()[0];
Object Object=ctor.newInstance(新对象[]{“ContstractorArgs”});
c、 getDeclaredMethods()[0]。调用(对象,对象…方法参数);
另一个有用的答案
在我的例子中,我的类的构造函数以Webdriver作为参数,因此使用以下代码:
return Class.forName("com.page.BillablePage")
.getConstructor(WebDriver.class)
.newInstance(this.driver);
使用
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);
}
}
案例2:-您可以为具有多个参数的构造函数编写类似的代码,并复制构造函数。例如,将3个参数作为参数传递给Base
构造函数将需要在类中创建构造函数,并在上面更改代码,如下所示:
Constructor<?> ctr = myClass.getConstructor(String.class, String.class, String.class);
Object object = ctr.newInstance(new Object[] { "Arg1", "Arg2", "Arg3" });
注意:-不要忘记处理代码中需要处理的各种异常。如果有人正在寻找一种方法来创建类的实例,尽管该类遵循单例模式,这里有一种方法
// 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 clazz=Class.forName(“myPackage.MyClass”);
//获取私有构造函数。
构造函数cons=clazz.getDeclaredConstructor();
//因为它是私有的,所以要让它可以访问。
cons.setAccessible(true);
//创建新对象。
Object obj=cons.newInstance();
这只适用于使用私有构造函数实现单例模式的类。
newInstance()
是一个varargs方法(就像GetConstructor()
),不需要显式创建对象
-数组。@Joachim:我知道是varargs,但当你有对象[]
argument,我更喜欢在本例中显式创建数组。clazz.getConstructor(String.class);为什么要在这里使用String.class?@Neutralizer:是的,但我回答了一个不需要动态的问题。@JonSkeet我知道你从哪里来,但这并不是那么简单-我确实看了文档,但感到困惑,但是,如果我测试了它,它成功了——好吧,那么它成功了——但是如果它不成功,那么我就不确定问题是否是由于缺乏配置或我自己的原因——通常在问这样简单的问题时,人们会抛出有用的花边新闻,这真的很有帮助。这就是为什么一个简单的“是的,那就行了——如果你这样做的话”或“不,没有办法”真的很有帮助。但我现在的理解是,如果使用默认构造函数,则无法删除String.class参数值,例如返回class.forName(className).getConstructor().newInstance(arg)@我想你的意思是Class.forName(className).getConstructor().newInstance()代码>;)这就是帮助我的原因Constructor=clazz.getConstructor(String.class)
似乎对我不起作用。另一种方法是通过克隆()现有java对象。这将创建现有Java对象的副本。对于这种情况,您还必须处理深度复制或浅层复制概念。您如何知道第一个构造函数将String
作为参数?当您更改构造函数时,会变得有点混乱order@Farid从类文档中仍然getConstructor(ClassName.class)
更好,我想。即使类中构造函数的顺序发生变化,也不需要找到位置manually@Farid-c.getDeclaredMethods()[0]。调用(对象,对象…方法参数);指定特殊构造函数在某些情况下您可能需要它;但你是对的。
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.
}
}
// 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();