Философия Java

Использование импорта для изменения поведения


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

Однако, есть и другая необходимость в условной компиляции. Самое распространенное использование - отладочный код. Отладка включается в процессе разработки, и отключается в конечном продукте. Аллен Холуб (Allen Holub) (www.holub.com) предложил идею - использования пакетов, для имитации условной компиляции. Он использовал это для создания Java-версии очень полезного механизма контроля (assertion) из языка C, с помощью которого Вы можете сказать “это должно быть истинно” либо “это должно быть ложно” и, если выражение не удовлетворяет этому контролю, Вы узнаете об этом. Такой инструмент является очень полезным во время отладки.

Вот класс, который Вы можете использовать для отладки:

//: com:bruceeckel:tools:debug:Assert.java

// Инструмент контроля для отладки.

package com.bruceeckel.tools.debug;

public class Assert { private static void perr(String msg) { System.err.println(msg); } public final static void is_true(boolean exp) { if(!exp) perr("Assertion failed"); } public final static void is_false(boolean exp){ if(exp) perr("Assertion failed"); } public final static void is_true(boolean exp, String msg) { if(!exp) perr("Assertion failed: " + msg); } public final static void is_false(boolean exp, String msg) { if(exp) perr("Assertion failed: " + msg); } } ///:~

Этот класс просто инкапсулирует булевские тесты, и печатает сообщение об ошибке, если эти тесты завершаются неудачно. В Главе 10, Вы познакомитесь с более изощренным инструментом для борьбы с ошибками, называемым обработка исключений, а пока метод perr( ) будет отлично работать.


Результат отправляется на консоль в поток стандартных ошибок - System.err.

Когда Вам необходимо использовать этот класс, Вы добавляете одну строку в свою программу:

import com.bruceeckel.tools.debug.*;

Для отключения этого контроля, Вы можете использовать код, где реализован второй класс Assert, находящийся в другом пакете:



//: com:bruceeckel:tools:Assert.java

// Отключение контроля

package com.bruceeckel.tools;

public class Assert { public final static void is_true(boolean exp){} public final static void is_false(boolean exp){} public final static void is_true(boolean exp, String msg) {} public final static void is_false(boolean exp, String msg) {} } ///:~

Так, если Вы измените предыдущее выражение import на:

import com.bruceeckel.tools.*;

программа больше не будет печатать контрольные данные. Вот пример:

//: c05:TestAssert.java

// Демонстрация инструмента контроля.

// Комментируете первую или вторую строчку и

// получаете различные результаты:

import com.bruceeckel.tools.debug.*; // import com.bruceeckel.tools.*;

public class TestAssert { public static void main(String[] args) { Assert.is_true((2 + 2) == 5); Assert.is_false((1 + 1) == 2); Assert.is_true((2 + 2) == 5, "2 + 2 == 5"); Assert.is_false((1 + 1) == 2, "1 +1 != 2"); } } ///:~

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


Содержание раздела