У меня есть класс утилит U, который зависит от библиотеки X и должен идти в пакете, который будет использоваться из программ с доступным X (где он должен делать свои обычные вещи) и места без X (где он ничего не должен делать). Без разделения класса на две части, я нашел простой шаблон, который решает эту проблему:Java-класс с возможно отсутствующими зависимостями во время выполнения
package foo;
import bar.MisteriousX;
public class U {
static private boolean isXPresent = false;
static {
try {
isXPresent = (null != U.class.getClassLoader().loadClass("bar.MisteriousX"));
} catch (Exception e) {
// loading of a sample X class failed: no X for you
}
}
public static void doSomething() {
if (isXPresent) {
new Runnable() {
public void run() {
System.err.println("X says " + MisteriousX.say());
}
}.run();
} else {
System.err.println("X is not there");
}
}
public static void main(String args[]) { doSomething(); }
}
С помощью этой модели, U требует X подарка для компиляции, но работает, как ожидалось при запуске с или без X настоящего. Если все обращения к библиотеке X находятся внутри внутренних классов, этот код запускает исключение класса loader.
Вопросы: разрешение импорта гарантировано, что оно работает везде, или это будет зависеть от реализации JVM/ClassLoader? Устанавливается ли это для этого? Является ли вышеописанный фрагмент кода слишком хакерским для его производства?
Вот почему у вас есть фреймворки, подобные пружине для инъекций зависимостей.В любом случае, я думаю, вы должны использовать интерфейс здесь, который всегда будет доступен, а не проверяет существование класса. – TedTrippin