Создание экземпляра с использованием имени класса и вызывающего конструктора

Есть ли способ создать экземпляр определенного класса, учитывая имя класса (dynamic) и передать параметры его конструктору.

Что-то вроде:

Object object = createInstance("mypackage.MyClass","MyAttributeValue");

Где "MyAttributeValue" - аргумент конструктору MyClass.

Ответ 1

Да, что-то вроде:

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").

Ответ 2

Вы можете использовать Class.forName(), чтобы получить Class объекта желаемого класса.

Затем используйте getConstructor(), чтобы найти желаемый Constructor.

Наконец, вызовите newInstance() на этом объекте, чтобы получить новый экземпляр.

Class<?> c = Class.forName("mypackage.MyClass");
Constructor<?> cons = c.getConstructor(String.class);
Object object = cons.newInstance("MyAttributeValue");

Ответ 3

Вы можете использовать отражения

return Class.forName(className).getConstructor(String.class).newInstance(arg);

Ответ 4

Если класс имеет только один пустой конструктор (например, Activity или Fragment и т.д., классы Android):

Class<?> myClass = Class.forName("com.example.MyClass");    
Constructor<?> constructor = myClass.getConstructors()[0];

Ответ 5

при использовании (т.е.) getConstructor(String.lang) конструктор должен быть объявлен открытым. В противном случае выдается a NoSuchMethodException.

если вы хотите получить доступ к непубличному конструктору, вы должны использовать вместо него (т.е.) getDeclaredConstructor(String.lang).

Ответ 7

Очень простой способ создания объекта в Java с помощью Class<?> с аргументом (-ами) конструктора:

Случай 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.
    }   
}

Примечание: - Не забывайте обрабатывать различные исключения, которые необходимо обрабатывать в коде.

Ответ 8

Вы также можете вызывать методы внутри созданного объекта.

Вы можете создать мгновение объекта, вызывая первый конструктор, а затем вызывать первый метод в созданном объекте.

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

Ответ 9

Если кто-то ищет способ создания экземпляра класса, несмотря на класс, следующий за шаблоном 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();

Это работает только для классов, реализующих одноэлементный шаблон с использованием частного конструктора.

Ответ 10

Еще один полезный ответ. Как использовать 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);