Условная компиляция Java
Я давний программист на С++, новый для Java. Я разрабатываю проект Java Blackberry в Eclipse. Вопрос. Есть ли способ внедрить различные конфигурации в проект, а затем скомпилировать немного другой код на основе этих данных?
В Visual Studio у нас есть конфигурации проектов и #ifdef; Я знаю, что там нет #ifdef в Java, но может быть что-то на уровне файлов?
Ответы
Ответ 1
Вы можете настроить "окончательные" поля и ifs, чтобы заставить компилятор оптимизировать скомпилированные байт-коды.
...
public static final boolean myFinalVar=false;
...
if (myFinalVar) {
do something ....
....
}
Если "myFinalVar" является ложным при компиляции кода, бит "сделать что-то..." будет пропущен из скомпилированного класса. Если у вас более одного условия - это можно немного подобрать: переведите их все в другой класс (скажем, "Config.myFinalVar" ), а затем все условия могут быть сохранены в одном аккуратном месте.
Этот механизм описан в 'Hardcore Java'.
[На самом деле, я думаю, что это тот же самый механизм, что и "бедный человек ifdef", опубликованный ранее.]
Ответ 2
вы можете управлять разными путями классов, например, реализовывать каждое "действие" в наборе различных каталогов:
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
Ответ 3
Если вы хотите это специально для BlackBerry, BlackBerry JDE имеет препроцессор:
Вы можете включить предварительную обработку для ваших приложений, обновив файл конфигурации 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
Подробности см. В разделе " Определение определений препроцессора".
Ответ 4
В JDK6 вы можете сделать это, используя интерфейс Java ServiceLoader.
Проверьте здесь.
Ответ 5
Можно ли назвать это бедным mans ifdef
: http://www.javapractices.com/topic/TopicAction.do?Id=64?
Ответ 6
Нет, Java не имеет точного соответствия для этой функции. Вы можете использовать аспекты или использовать контейнер IOC для ввода различных классов реализации.
Ответ 7
Вы можете использовать фильтрацию ресурсов maven в сочетании с общедоступными статическими конечными полями, которые будут действительно скомпилированы условно.
private static final int MODE = ${mode};
...
if (MODE == ANDROID) {
//android specific code here
} else {
}
Теперь вам нужно добавить свойство к вашему maven pom, называемому "mode", который должен быть
того же значения, что и константа ANDROID.
Компилятор java должен (!) удалить блок if и else, оставив ваш код Android.
Не testet, поэтому нет гарантии, и я предпочитаю конфигурацию вместо условной компиляции.
Ответ 8
Вы можете интегрировать m4 в свой процесс сборки, чтобы эффективно привязать аналог к препроцессору C перед компилятором Java. Многое размахивание руками заключается в шаге "интегрировать", но m4 является правильной технологией для задания обработки текста.
Ответ 9
Помимо Maven, Ant и других инструментов сборки, которые обеспечивают аналогичную функциональность, можно было бы построить интерфейсы в Java и переключить реализации в Runtime.
Подробнее см. Шаблон стратегии.
В противоположность C/С++ это не будет иметь большой производительности, так как Javas-компилятор Javas оптимизируется во время выполнения и может вставлять эти шаблоны в большинстве случаев.
Большой профессионал этого шаблона - гибкость - вы можете изменить базовую реализацию, не касаясь основных классов.
Вы также должны проверить IoC и шаблон наблюдателя для более подробной информации.
Ответ 10
В eclipse вы можете использовать несколько проектов
Версия 1 и вторая версия содержат одни и те же файлы, но разные реализации. В Main вы обычно пишете, например.
import org.mycustom.Version;
И если вы включили проект Version1/Version2 в качестве ссылки, он скомпилируется с файлом Version.java из проекта Version1/Version2.
Ответ 11
Есть несколько проектов, которые предоставляют поддержку условной компиляции на основе комментариев в Java:
Пример в JPSG:
/* with Android|Iphone platform */
class AndroidFoo {
void bar() {
/* if Android platform */
doSomething();
/* elif Iphone platform */
doSomethingElse();
/* endif */
}
}