Как использовать переменную класса String в имени создаваемого класса?

239
13 ноября 2017, 18:52

Есть переменная:

String name_class = "name1";

Есть класс:

MyClass

Хочу создать экземпляр класса используя переменную для имени:

MyClass name_class = new MyClass;

Но такая форма не прокатывает.

Как правильно написать?

И еще, как используя переменную name_class, найти класс с таким именем и обратиться к нему? Например, как то так:

find(name1).getNum(int num);
Answer 1

Создать класс по имени, используя рефлексию, можно.

Если у вас есть класс, например:

public static class MyClass {
    public MyClass() {
    }
    public String justForTests() {
        return "test";
    }
}

Создать экземпляр можно так:

try {
    Class<?> clazz = Class.forName(MyClass.class.getName());
    Constructor<?> ctor = clazz.getConstructor();
    MyClass app = (MyClass)ctor.newInstance();
    System.out.println(app.justForTests());
}
catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    e.printStackTrace();
}

В вашем случае будет так:

String name_class = "полное_имя_класса";
Class<?> clazz = Class.forName(name_class);

Но нужно помнить, что name_class - полное имя класса с пакетом, то есть, если класс лежит в пакете ru.tests, то должно быть так в итоге:

try {
    String name_class = "ru.tests.MyClass";
    Class<?> clazz = Class.forName(name_class);
    MyClass app = (MyClass)ctor.newInstance();
    System.out.println(app.justForTests());
}
catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    e.printStackTrace();
}
Answer 2

Есть классы MyClass1, MyClass2...MyClassN, (наследники одного класса MyClass) которые содержит какие-то переменные. Из таких классов хочу создать ArrayList l_my_class. Выдергивать их из ArrayList хочу по названию класса. l_my_class.get(l_my_class.indexOf("MyClass1")).

Сохранение:

 Map<Class<? extends MyClass>, ? extends MyClass> map = new HashMap<>();
 map.put(MyClass1.class, new MyClass1(...)); 
 ...
 map.put(MyClassN.class, new MyClassN(...));

Получение:

 MyClass obj = map.get(MyClass1.class); 

Если вам именно хочется строку (хотя класс куда правильнее), то можно так

 Map<String, ? extends MyClass> map = new HashMap<>();
 map.put(MyClass1.class.getName(), new MyClass1(...)); 
 ...
 map.put(MyClassN.class.getName(), new MyClassN(...));
 MyClass obj = map.get(MyClass1.class.getName()); 

P.S. Не знаю вашу задачу, но есть большое подозрение, что можно решить ее без использования таких структур. Посмотрите паттерн фабрика/фабричный метод и ему подобные, либо вообще Dependency Injection.

READ ALSO
Java synchronized блокирует класс а не объект?

Java synchronized блокирует класс а не объект?

Добрый день, недавно читал Брюса Эккеля, и наткнулся на такую проблему: блок synchronized(Object) блокирует класс обьекта, е не сам обьектК такому выводу...

246
BLE как отправлять данные &lt;20 бит

BLE как отправлять данные <20 бит

Собрал проект по данным исходникам переделал под свои нуждыИ возникла необходимость отправлять данные более 20 бит

262
Серверное приложение для всех ОС на Java

Серверное приложение для всех ОС на Java

ЗдравствуйтеРешил я улучшить свои навыки программирования и работы с базами данных

228