Создать новый класс из переменной в Java
Есть ли способ создать новый класс из переменной String в Java?
String className = "Class1";
//pseudocode follows
Object xyz = new className(param1, param2);
Кроме того, если возможно, должен ли результирующий объект иметь тип Object?
Может быть, есть лучший способ, но я хочу иметь возможность получать значения из файла XML, а затем создавать классы, названные в честь этих строк. Каждый из классов реализует один и тот же интерфейс и является производным от одного и того же родительского класса, поэтому я мог бы вызвать определенный метод в этом классе.
6 ответов
Это то, что вы хотите сделать:
String className = "Class1";
Object xyz = Class.forName(className).newInstance();
Обратите внимание, что метод newInstance не позволяет использовать параметризованный конструктор. (См. Документацию Class.newInstance)
Если вам нужно использовать параметризованный конструктор, это то, что вам нужно сделать:
import java.lang.reflect.*;
Param1Type param1;
Param2Type param2;
String className = "Class1";
Class cl = Class.forName(className);
Constructor con = cl.getConstructor(Param1Type.class, Param2Type.class);
Object xyz = con.newInstance(param1, param2);
Да, вы можете загрузить класс на ваш путь к классу, используя имя String, используя отражение, используя Class.forName(name), захватывая конструктор и вызывая его. Я сделаю тебе пример.
Считайте, что у меня есть класс:
com.crossedstreams.thingy.Foo
У которого есть конструктор с подписью:
Foo(String a, String b);
Я бы создал экземпляр класса на основе этих двух фактов следующим образом:
// Load the Class. Must use fully qualified name here!
Class clazz = Class.forName("com.crossedstreams.thingy.Foo");
// I need an array as follows to describe the signature
Class[] parameters = new Class[] {String.class, String.class};
// Now I can get a reference to the right constructor
Constructor constructor = clazz.getConstructor(parameters);
// And I can use that Constructor to instantiate the class
Object o = constructor.newInstance(new Object[] {"one", "two"});
// To prove it's really there...
System.out.println(o);
Выход:
com.crossedstreams.thingy.Foo@20cf2c80
Существует множество ресурсов, которые более подробно рассказывают об этом, и вы должны знать, что вы вводите зависимость, которую компилятор не может проверить за вас - если вы неправильно введете имя класса или что-то еще, во время выполнения произойдет сбой., Кроме того, есть довольно много различных типов Исключений, которые могут быть выброшены во время этого процесса. Это очень мощная техника.
Это должно работать:
import java.lang.reflect.*;
FirstArgType arg1;
SecondArgType arg2;
Class cl = Class.forName("TheClassName");
Constructor con = cl.getConstructor(FirstArgType.class, SecondArgType.class);
Object obj = con.newInstance(arg1, arg2);
Оттуда вы можете привести к известному типу.
В JDK7 это сработало немного более чисто, в то время как приведенные выше ответы усложнили ситуацию с точки зрения новичка: (предполагается, что вы объявили "className" как переменную String, переданную как параметр метода или ранее в методе с использованием этого кода):
Class<?> panel = Class.forName( className );
JPanel newScreen = (JPanel) panel.newInstance();
С этого момента вы можете использовать свойства / методы из вашего динамически названного класса точно так, как вы ожидаете, что сможете использовать их:
JFrame frame = new JFrame(); // <<< Just so no-one gets lost here
frame.getContentPane().removeAll();
frame.getContentPane().add( newScreen );
frame.validate();
frame.repaint();
Примеры в других ответах выше привели к ошибкам, когда я попытался.add() новый объект типа "Объект" к фрейму. Методика, показанная здесь, дала мне полезный объект с этими двумя строками кода выше.
Не совсем уверен, почему это так - я сам новичок на Java.
Пример программы для получения экземпляра class
с помощью String
Объект.
public class GetStudentObjectFromString
{
public static void main (String[] args) throws java.lang.Exception
{
String className = "Student"; //Passed the Class Name in String Object.
//A Object of Student will made by Invoking its Default Constructor.
Object o = Class.forName(className).newInstance();
if(o instanceof Student) // Verify Your Instance that Is it Student Type or not?
System.out.println("Hurrey You Got The Instance of " + className);
}
}
class Student{
public Student(){
System.out.println("Constructor Invoked");
}
}
Выход:-
Constructor Invoked Hurrey You Got The Instance of Student
Другой:
import java.lang.reflect.Constructor;
public class Test {
public Test(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return this.name;
}
private String name;
public static void main(String[] args) throws Exception {
String className = "Test";
Class clazz = Class.forName(className);
Constructor tc = clazz.getConstructor(String.class);
Object t = tc.newInstance("John");
System.out.println(t);
}
}