Условная компиляция Java - PullRequest
20 голосов
/ 17 декабря 2009

Я давний программист на C ++, новичок в Java. Я разрабатываю проект Java Blackberry в Eclipse. Вопрос - есть ли способ ввести различные наборы конфигурации в проект, а затем скомпилировать немного другой код, основанный на них?

В Visual Studio у нас есть настройки проекта и #ifdef; Я знаю, что в Java нет #ifdef, но, возможно, что-то на уровне файлов?

Ответы [ 11 ]

15 голосов
/ 17 декабря 2009

Вы можете установить поля 'final' и ifs, чтобы компилятор оптимизировал скомпилированные байт-коды.

...
public static final boolean myFinalVar=false;
...
if (myFinalVar) { 
 do something ....
 ....
}

Если для myFinalVar задано значение false, когда код компилируется, бит «сделать что-то ....» будет пропущен в скомпилированном классе. Если у вас есть более одного условия - это можно немного привести в порядок: переместите их все в другой класс (скажем, «Config.myFinalVar»), и тогда все условия можно будет сохранить в одном удобном месте.

Этот механизм описан в 'Hardcore Java'.

[На самом деле я думаю, что это тот же механизм, что и "ifdef для бедняка", опубликованный ранее.]

6 голосов
/ 18 декабря 2009

Если вы хотите это специально для BlackBerry, BlackBerry JDE имеет предварительный процессор :

You может включить предварительную обработку для вашего приложения путем обновления Eclipse ™ файл конфигурации.

В C: \ Program Files \ Eclipse \ configuration \ config.ini, добавьте следующую строку: osgi.framework.extensions = net.rim.eide.preprocessing.hook Если вы включите предварительную обработку после того, как вы была сборка, вы должны очистить проект из меню проекта до Вы строите проект снова.

Тогда вы можете делать такие вещи в коде, как:

//#ifdef SOMETHING
// do something here
//#else
// do something else
//#endif

Подробнее см. Определение препроцессора определяет

6 голосов
/ 17 декабря 2009

вы можете управлять различными путями к классам, например, реализовывать каждое действие в наборе различных каталогов:

dir1/Main.java
dir2/Action.java
dir3/Action.java

затем используйте разные пути к классам для каждой версии

javac -sourcepath dir1 -cp dir2 dir1/Main.java

или

javac -sourcepath dir1 -cp dir3 dir1/Main.java
5 голосов
/ 17 декабря 2009

В JDK6 вы можете сделать это с помощью интерфейса Java ServiceLoader. Проверьте это здесь .

4 голосов
/ 17 декабря 2009

Можно ли назвать это бедняком ifdef: http://www.javapractices.com/topic/TopicAction.do?Id=64?

3 голосов
/ 17 декабря 2009

Нет, Java не имеет точного соответствия для этой функции.Вы можете использовать аспекты или использовать контейнер IOC для внедрения различных классов реализации.

1 голос
/ 08 апреля 2019

Существует несколько проектов, которые предоставляют поддержку условной компиляции на основе комментариев в Java:

Пример в JPSG:

/* with Android|Iphone platform */
class AndroidFoo {
  void bar() {
    /* if Android platform */
    doSomething();
    /* elif Iphone platform */
    doSomethingElse();
    /* endif */
  }
}
1 голос
/ 17 декабря 2009

Помимо Maven, Ant и других инструментов сборки, которые предоставляют аналогичную функциональность, лучше было бы создавать интерфейсы в Java и переключать реализации во время выполнения.
См. шаблон стратегии для более подробной информации

В отличие от C / C ++ это не приведет к значительному снижению производительности, поскольку JIT-компилятор Javas оптимизирует во время выполнения и в большинстве случаев может использовать эти шаблоны.
Основным преимуществом этого шаблона является гибкость - вы можете изменить базовую реализацию, не затрагивая основные классы.

Вам также следует проверить IoC и Шаблон наблюдателя для получения более подробной информации.

1 голос
/ 17 декабря 2009

Вы можете интегрировать m4 в процесс сборки, чтобы эффективно связать аналог препроцессора C перед компилятором Java. Большая часть размахивания руками лежит на этапе «интеграции», но m4 - правильная технология для работы по обработке текста.

1 голос
/ 17 декабря 2009

Вы можете использовать фильтрацию ресурсов maven в сочетании с открытыми статическими полями final, которые действительно будут скомпилированы условно.

private static final int MODE = ${mode};

...

if (MODE == ANDROID) {
    //android specific code here
} else {

}

Теперь вам нужно добавить свойство в свой maven pom под названием «mode», которое должно быть того же значения, что и ваша константа ANDROID.

Java-компилятор должен (!) Удалить блоки if и else, оставив при этом ваш код Android.

Не тест, так что нет гарантии, и я бы предпочел конфигурацию вместо условной компиляции.

...