Разница заключается в том, что new AireBatchDaoFactory
создаст экземпляр , что конкретный класс (или не компилировать, если AireBatchDaoFactory
является интерфейсом или абстрактным классом). Но factory
может содержать полное имя любого класса, который реализует AireBatchDaoFactory
(если это интерфейс) или подклассы его (если это класс). Class.forName(factory).newInstance()
загрузит класс с именем factory
и создаст его новый экземпляр.
Это довольно распространенный шаблон для плагинов времени выполнения для кодовой базы. Обычно вы определяете интерфейс, который реализуют плагины. Затем вы предоставляете средство времени выполнения для указания того, какой конкретный класс использовать (в файле свойств, в некоторых других конфигурациях и т. Д.), И используйте Class.forName
для загрузки класса и newInstance
для создания экземпляра его. Поскольку класс определяется по адресу runtime, это может быть то, что авторы использующего его кода никогда не видели, написаны долго после кода, который его использует. Следовательно, используя его для плагинов.
Рассмотрим:
Plugin.java
:
interface Plugin {
void doSomething();
}
Foo.java
:
public class Foo implements Plugin {
public void doSomething() {
System.out.println("I'm Foo");
}
}
Bar.java
:
public class Bar implements Plugin {
public void doSomething() {
System.out.println("I'm Bar");
}
}
App.java
:
public class App {
public static final void main(String[] args) {
try {
String classToLoad = args[0];
Plugin plugin = Class.forName(classToLoad).newInstance();
plugin.doSomething();
}
catch (Exception e) {
//...handle error...
}
}
}
Запуск
java App Foo
...загружает класс Foo
и звонит doSomething
, давая нам "I'm Foo"
.
Запуск
java App Bar
... загружает Bar
класс и вызывает doSomething
на него, давая нам "I'm Bar"
.
Это называется ** отражение **. Существует строка 'String', описывающая FQCN' class', и код пытается преобразовать этот 'String' сначала в экземпляр класса, а затем в новый экземпляр этого' class', предполагая конструктор по умолчанию. Это ** только ** способ создания экземпляра из 'String' -' new', очевидно, не будет работать здесь. –
Написание только 'return class.forName (factory) .newInstance();' могло быть общим, остальное кажется таким же. Кроме того, захватывая супер 'Exception' и бросая' SQLException' вместо 'ClassNotFoundException', возможно, кто-то изменил бы это в течение определенного периода времени. Даже без использования переменной 'ORACLE_FACTORY' –
Кроме того, обычно эти заводы являются _abstract classes_ (как и в вашем случае), которые не могут быть созданы. Бросок необходим для выполнения подписи метода (а также может быть неудачным). – Seelenvirtuose