#java
#java
Вопрос:
Я наткнулся class.forname.newInstance
при поиске creating objects by String
. Я знаю, что использование первого метода занимает больше времени, чем использование ключевого new
слова, но насколько дольше? Если я хочу создать экземпляр из 100 классов, которые у меня есть, на основе значения a String
, сколько времени это займет? Во время выполнения лучше выполнять только 100 операторов if (я не против этого, правда ..)?
Комментарии:
1. Есть ли у всех этих классов общий супертип?
2. Да, все они имеют один и тот же конструктор и расширяют один и тот же класс.
Ответ №1:
Использование оператора new выполняется очень быстро и оптимизировано, поскольку оно выполняет построение во время компиляции.
Class.forName().newInstance() выполняет динамическое построение, которое намного медленнее, чем оператор new, поскольку тип объекта не всегда известен во время выполнения, и некоторые оптимизации виртуальной машины Java не могут быть выполнены.
Кроме того, отражение имеет ограничения безопасности, поскольку они всегда требуют разрешения на время выполнения при запуске под управлением Security Manager, я настоятельно не рекомендую использовать отражение, если у вас нет на это особых причин.
Чтобы ответить на ваш точный вопрос, если вы предпочитаете Class.forName().newInstance(), это обойдется вам в 4 раза дороже (по крайней мере, в моей системе, когда я тестировал код для 100 операций), чем оператор new .
Ответ №2:
Поскольку у вас есть 100 возможных подклассов, написание 100 if
кажется очень подробным и подверженным ошибкам.
Как сказал arunprakashpj, я бы не стал использовать отражение по тем же причинам, однако я бы тоже не использовал 100 if
. Вместо этого я сделаю следующее, чтобы немного уменьшить детализацию, но все же используя new
оператор:
Map<String, Supplier<YourBaseClass>> constructors = new HashMap<>();
constructors.put("Impl1", Impl1::new);
constructors.put("Impl2", Impl2::new);
...
Затем вы можете создать ImplXXX
подобное (никаких ifs не требуется):
private static YourBaseClass construct(String classname) {
return constructors.getOrDefault(classname, DummyImpl::new).get();
}