Java: создание объектов на основе строки с использованием class.forname.newinstance против операторов if

#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();
}