LINUX.ORG.RU

Создание экземпляров классов по ключу

 


0

1

Допустим у нас есть базовый класс Base, и наследники: A, B, C, D. С каждым из наследников связан свой String. Задача в том, чтобы создавать экземпляры наследников согласно String.

HashMap<String , Class<? extends Base>> hm = new HashMap<String , Class<? extends Base>>() ;
hm.put("one", A.class);
hm.put("two", B.class);
hm.put("three", C.class);
hm.put("four", D.class);

Class <? extends Base> val = hm.get("one");
Base a = val.newInstance();
val = hm.get("two");
Base b = val.newInstance();
...

В жабе слабоват и не знаю как правильно такую штуку реализовать.



Последнее исправление: ApostolPetr (всего исправлений: 2)

Твой вариант будет работать.

Хотя в данном случае можно обойтись без рефлексии:

static Base createBase(String name) {
    switch (name) {
        case "one": return new A();
        case "two": return new B();
        default: throw new RuntimeException("Unknown name: " + name);
    }
}

Legioner ★★★★★
()
Ответ на: комментарий от ApostolPetr

Это прямо пропорционально частоте создания классов по строкам. Нечасто создаются — несильно проигрывает. Часто — сильно.

ilammy ★★★
()
Ответ на: комментарий от ApostolPetr

По производительности надо мерять.

Есть ещё такой вариант:

abstract interface BaseFactory {
    Base create();
}
class AFactory implements BaseFactory {
    public Base create() { return new A(); }
}
...
Map<String, BaseFactory> baseFactoryRegistry = new ...;
baseFactoryRegistry.put("one", new AFactory());
...

BaseFactory factory = baseFactoryRegistry.get(str);
Base base = factory.create();

но это уже из разряда паттерн на паттерне паттерном погоняет.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)

Задача звучит как получение компоненты по имени. Зачем изобретать велосипед, если такое уже давно написано? Напримерм в Spring.

ii
()
Ответ на: комментарий от Legioner

но это уже из разряда паттерн на паттерне паттерном погоняет.

Тем не менее, это самый правильный вариант, хотя в эпоху тотального быстрокодинга, быдлокодинга и готовых псевдорешений всякое может быть.

dave ★★★★★
()

навскидку:

new Class(«ClassName»);

bvn13 ★★★★★
()

1. in Base: protected HashMap<String , Class<? extends Base>> hm = new HashMap<String , Class<? extends Base>>() ;

and in Base: public Class <? extends Base> GetByString(String s){ return new hm.get(s); // эээээ }

in evry child (only, not grandchild :( )

class childX extend Base{ static{hm.put(«stringGUID»,childX );//*ZZZ* } }

строчку с *ZZZ* нужно по культурней - мысль что базовый - менеджит кого по ключу создать , ребёнок регестрируется у менеджера - ненужно каждый раз переписывать менеджера для прикручивания нового ребёнка.

что хэш на строках , что свич - скорость сопоставима и там и там сравнение ссылок на иммутабельные строки

qulinxao ★★☆
()

Всем спасибо за помощь, реализовал как предложил qulinxao.

ApostolPetr
() автор топика

Если классов мало - можно воспользоваться Enum'ами. Их можно создавать по строковому представлению, и прописать метод в каждом для создания конкретного класса. Как то так.

TheKnight ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.