Есть ли способ создать экземпляр определенного класса с именем класса (динамический) и передать параметры его конструктору.
Что-то вроде:
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 ()
][3], чтобы найти нужный объект Constructor
.
Наконец, вызовите [newInstance ()
][5] на этом объекте, чтобы получить новый экземпляр.
Class<?> c = Class.forName("mypackage.MyClass");
Constructor<?> cons = c.getConstructor(String.class);
Object object = cons.newInstance("MyAttributeValue");
[3]: http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#getConstructor%28java.lang.Class...% 29
Вы можете использовать отражения
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)
конструктор должен быть объявлен публичным.
В противном случае бросается «NoSuchMethodException».
если вы хотите получить доступ к непубличному конструктору , вы должны использовать его вместо этого (т.е.) getDelaredConstructor (String.lang)
.
Вы хотите использовать [java.lang.reflect.Constructor.newInstance (Объект...)][1]
Очень простой способ создать объект на 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.
}
}
Примечание: - Не забудьте обработать различные исключения, которые необходимо обработать в коде.
Вы также можете вызывать методы внутри созданного объекта.
Вы можете создать объект мгновенно, вызвав первый конструктор, а затем вызвать первый метод в созданном объекте.
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);
Еще один полезный ответ. Как использовать getConstructor (параметры) .newInstance (арги)?
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);
Если кто-то ищет способ создать экземпляр класса, несмотря на то, что класс следует шаблону Синглтона, вот способ сделать это.
// 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();
Это работает только для классов, которые реализуют однотонный шаблон с использованием частного конструктора.