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