Visual J++ поддерживает два новых механизма условной компиляции в Java: директивы и методы
условной компиляции. В таблице, приведенной ниже, описаны все директивы условной
компиляции, а общие сведения о них даны в разделе «Директивы условной
компиляции». Краткое описание синтаксиса и примеры использования методов
условной компиляции см. в разделе «Методы условной компиляции» далее
в этом приложении.
Примечание
Эти механизмы относятся к расширениям языка Java, разработанным Microsoft.
Поэтому исходный код, в котором задействованы эти механизмы, некорректно компилируется
другими средствами разработки Java-программ.
Директива
условной компиляции |
Описание |
||
#if |
Включает или
исключает блоки кода из компиляции в зависимости от значения условного
выражения или идентификатора. |
||
#elif |
Дополняет директиву
#if. Если предшествующая проверка условия #if дает false, #elif включает
или исключает блоки кода из компиляции в зависимости от значения своего
выражения или идентификатора. |
||
#else |
Дополняет директиву
#if. Если предшествующая проверка условия #lf дает false, компилируется
блок кода, следующий за #else. |
||
#endif |
Требуется при
использовании директивы #if. Завершает блок кода, компилируемый по
условию. |
||
#define |
Определяет идентификатор
для препроцессора. |
||
#error | При компиляции генерирует сообщение об ошибке, определенной программистом. | ||
#warning | При компиляции генерирует предупреждение, определенное программистом. | ||
#undef |
Отменяет определение
идентификатора для препроцессора. |
||
Директивы
условной компиляции #if, #elif, #else и #endif
Директивы
#if, #elif, #else и #endif позволяют включать или исключать блоки исходного
кода из компиляции по неким условиям. У директивы #if, с которой начинаются
все условные блоки, должна быть парная директива #endif.
Синтаксис
#if <выражение1>
включаемый
блок #elif <выражение2>
включаемый
блок #else
включаемый
блок #endif
Выражение,
следующее за #if и #endif, должно быть допустимым логическим выражением, которое
состоит из Булевых операторов и использует идентификаторы, объявленные директивами
#define и #undef. Если выражение в #if дает true, следующие за ней строки подлежат
компиляции, а если оно — false, все строки до соответствующей директивы #elif,
#else или #endif из компиляции исключаются. В блоке условной компиляции допустима
лишь одна директива #else. Строки, расположенные за ней, подлежат компиляции,
только если выражение в соответствующей директиве #if ложно. А директива #elif
может появляться в таком блоке произвольное число раз (или вовсе отсутствовать).
Выражениям,
применяемым в условной компиляции, свойственны все ограничения и особенности
языка Java. Например, допустимы любые Булевы и побитовые операторы языка Java.
При этом действует тот же приоритет операторов, и его можно изменять так, как
принято в Java, — с использованием круглых скобок.
Следующий
пример иллюстрирует применение каждой из этих директив условной компиляции:
#define DEBUG
#undef RETAIL
public class
test {
#if DEBUG
if (cmdStatus.equals(invokeError))
{
// следующая строка выводит диагностическое сообщение: System.out.println("Error: command timed out.");
// здесь выполняются соответствующие действия
}
#elif RETAIL
if (cmdStatus.equals(invokeError))
// здесь выполняются соответствующие действия
}
#else
#error Must define DEBUG or RETAIL;
#endif
}
Директива
условной компиляции #define
Директива
#define включает в исходный файл идентификатор условной компиляции, который
после этого можно применять во всех классах, имеющихся в исходном файле. Эта
директива должна быть в начале исходного файла — предшествовать ей могут только
комментарии и другие директивы условной компиляции.
По соглашению
значение идентификатора, объявленного директивой #define, должно быть всегда
true.
Синтаксис
#define <идентификатор>
Идентификатор
состоит максимум из 1 024 символов и набирается только заглавными буквами.
Следующий
пример демонстрирует применение #define в Java-приложении:
#define DEBUG
// DEBUG присваивается true
#if DEBUG
// код, подлежащий
компиляции #endif
Примечание
Процесс сборки в Visual J++ не предусматривает задания параметров
отдельно для каждого файла. Поэтому, если Вы хотите включать и исключать идентификаторы
условной компиляции в индивидуальном исходном файле, объявляйте директивы #define
и #undef явным образом в каждом файле.
Директива
условной компиляции #undef
Директива
#undef удаляет идентификатор из исходного файла. Этот идентификатор не обязательно
должен быть определен, и, кроме того, Вы можете переопредить его в исходном
файле, используя директиву #define. Директиву #undef следует помещать в начало
исходного файла — предшествовать ей могут только комментарии и другие директивы
условной компиляции.
Синтаксис
#undef <идентификатор>
Идентификатор
состоит максимум из 1 024 символов, и набирается только заглавными буквами.
Следующий
пример демонстрирует применение #undef в Java-приложении:
#undef DEBUG
// DEBUG присваивается false
#if DEBUG
// код, исключаемый
из компиляции #endif
Примечание
Процесс сборки в Visual J + + не предусматривает задания параметров
отдельно для каждого файла. Поэтому, если Вы хотите включать и исключать идентификаторы
условной компиляции в индивидуальном исходном файле, объявляйте директивы #define
и #undef явным образом в каждом файле.
Директива
условной компиляции #error
Директива
#error принимает в качестве аргумента строку и при компиляции генерирует сообщение
об ошибке. Последние выводятся как обычные ошибки компилятора.
Подобно #warning,
эта директива наиболее полезна при предварительной обработке исходного файла
для выявления предопределенных ограничений и несоответствий.
Синтаксис
#error <строка_сообщения>
Этот идентификатор
строки сообщения указывает, какое сообщение об ошибке следует вывести. Применение
#error иллюстрирует такой пример:
#if DEBUG
#elif RETAIL
#else
#error DEBUG or RETAIL must be defined!
#endif
Компилятор,
встретив последнее определение, выведет строку: #error 'DEBUG or RETAIL must
be defined' (J0500)
Директива
условной компиляции #warning
Директива
#warning принимает в качестве аргумента строку и при компиляции генерирует предупреждение.
Последние выводятся как обычные предупреждения компилятора.
Подобно #error,
эта директива наиболее полезна при предварительной обработке исходного файла
для выявления предопределенных ограничений и несоответствий.
Синтаксис
#warning <строка
сообщении>
Этот идентификатор строки сообщения указывает, какое предупреждение следует вывести.
Применение
#warning иллюстрирует такой пример:
#if !TRACING
#warning This interface has not been completely tested yet!
#endif
Компилятор, встретив данное определение, выведет строку:
#warning 'This
interface has not been completely tested yet!' (J5500)
Метод условной
компиляции помечается тэгом @, встроенным в Java-doc-комментарий, и по результатам
проверки условия либо включается, либо исключается из исходного файла. Если
метод исключен из исходного файла, компилятор автоматически убирает его вызовы
из исходного кода программы.
Синтаксис
/** @conditional (выражение) */
void цмя_метода(аргументы)
{
}
Выражение
может быть любым, допустимым в Java, и использовать идентификаторы, объявленные
директивами #define или #undef. Главное достоинство методов условной компиляции
в том, что они упрощают включение или исключение больших объемов отладочной
информации. Например, позволяют генерировать важную диагностическую информацию
в процессе разработки программы. А как только разработка
завершена и приложение готово к выпуску, все методы условной компиляции и их
вызовы легко убираются простой модификацией значения идентификатора.
Применение
метода условной компиляции иллюстрирует следующий пример: #define DEBUG // DEBUG
присваивается true
public class
someClass {
/** @conditional
(DEBUG) */
trackDisplay(int
dTrack)
{
System.out.println("Variable
dTrack assigned: %d", dTrack);
} }
Здесь Вы
определяете идентификатор DEBUG и тем самым включаете в процесс компиляции метод
trackDisplay. Если этот метод больше не нужен, то, заменив #define на #undef,
Вы заставите компилятор исключить его из компиляции исходного файла и отменить
все обращения к нему из любого места программы.
Директивы
условной компиляции используются для включения или исключения блоков кода из
исходного файла по результатам оценки выражения или значения единственного идентификатора.
Они полезны на многих этапах разработки программ, в том числе для:
Применение
директив условной компиляции демонстрирует следующий пример:
#define PRINTHELLO // PRINTHELLO имеет значение true
public class
sample {
public static
void main(String args[]) {
#if PRINTHELLO
System.out.println("Hello!");
#eise
System.out.println("Goodbye.");
#endif } }
Здесь выводится
строка «Hello!». Если удалить директиву #define, будет отображаться
строка «Goodbye».
Как и в стандартных
условных конструкциях Java, в некоторых директивах условной компиляции (например,
в #if) применяются выражения, управляющие последовательностью выполнения этих
директив. Многие правила синтаксиса Java-операторов применимы и к выражениям
в директивах условной компиляции.
В строку
с директивой условной компиляции нельзя добавлять ничего, кроме однострочного
комментария.
Разумно применяя такие директивы, Вы сэкономите при отладке программы немало времени и сил.