Java - эталон независимости программы от платформы исполнения. Но, увы, даже отдельные версии Java не могут претендовать на полную совместимость. Версия Java 1.1 немного изменена по сравнению с Java 1.0. Это связано с поддержкой JavaBeans, в соответствии с которой Sun Microsystems переписала набор классов из пакета java.awt. Кроме того, поддержка в новой версии Java различных национальных языков потребовала модернизации некоторых классов пакета java.io. Чтобы заставить разработчиков переходить на новые API-интерфейсы, компилятор java версии 1.1 при обнаружении старых методов выдает соответствующее сообщение-возражение. В принципе в большинстве случаев переход на новую версию Java достаточно прост: нужно заменить старые методы новыми. Однако модель обработки событий, принятая в Java 1.1, требует более сложного преобразования кода программы на Java.
Следует отметить, что версия Java 1.1 применяется в новых браузерах Communicator от Netscape и Internet Explorer 4.0 производства Microsoft. Но не все пользователи Internet перешли на эти браузеры. Поэтому при программировании апплетов для Internet лучше всего ориентирваться и на старую версию Java. Таким образом, разработчикам Java-программ приходится полностью отказаться от версии Java 1.0 либо писать программы только для нее.
Последнее усложняется еще и тем, что большинство визуальных средств разработки использует новую версию Java. Решить эту проблему можно багодаря модульности Java.
В Си и C++ для дополнительной настройки на конкретную платформу служит препроцессор. Он позволяет скомпоновать код так, чтобы в программах для конкретной платформы использовались только присущие ей особенности. В Java такой возможности нет, но для настройки программы на конкретную платформу можно задействовать компонентную модель. Для этого необходимо вынести все зависимые от платформы или версии методы в отдельный модуль, написать его варианты для всех поддерживаемых диалектов Java, а затем при запуске Java-приложения на конкретной платформе подгружать только один, наиболее подходящий модуль. Пример такого метода настройки приведен на сервере JavaWorld Россия. Следует отметить, что примерно так же поступали и разработчики графического пользовательского интерфейса Java - AWT, которые вынесли все аппаратно-зависимые методы в отдельный пакет - java.awt.peer.
Метод настройки Java-программы на особенности реализации Java машины опирается на механизм системных свойств. Значение этих свойств можно получить с помощью статических методов getProperty() и getProperties() класса System. Среди системных свойств есть предопределенные разработчиками Java, но предусмотрен также механизм определения значения системных свойств при запуске Java-интерпретатора. Это можно сделать, например, с помощью следующей команды:
java -Ddebug=true myClass
Она запустит Java-приложение myClass с установленным системным свойством debug в значении true. Таким образом, механизм системных свойств позволяет не только настраивать Java-программу на определенную платформу, но и определять различные режимы работы самой программы.
Отдельным и очень важным пунктом применения свойств является настройка Java-приложения на различные национальные языки. Для этого создается файл свойств (формат примерно следующий: свойство=значение), который подгружается во время исполнения программы из локальной файловой системы. Таким образом, пользователь может самостоятельно перевести все сообщения, используемые программой в ее работе. Пример такого файла свойств, который задействует в своей работе VisualAge for Java для настройки на русские шрифты, приведен на сервере JavaWorld Россия. Аналогичные методы русификации можно использовать и в других реализациях Java. Пример программы на Java, которая ориентирована на поддержку различных языков, можно найти на сервере издательства O'Reilly по адресу http://www.oreilly.com/catalog/javanut2/ examples/ch11/LocalizedError.java.
Следует отметить, что, хотя мы ведем речь об аппаратно-зависимых элементах Java-программы, их использование, как ни парадоксально, не нарушает принципа аппаратной независимости. Дело в том, что на Java можно написать код, который будет работать на всех платформах, однако принцип «безобразно, но единообразно» не всегда приемлем в программировании. Иногда приходится обращаться к дополнительным возможностям конкретной, наиболее распространенной платформы, а для всех остальных использовать универсальный код. Поэтому важно, чтобы по умолчанию в программе применялся универсальный модуль и только в особых случаях загружался оптимизированный. Замечу, что для различных версии Java универсальным будет модуль, написанный в соответствии со стандартом Java 1.0, так что именно он должен грузиться по умолчанию. Однако не стоит злоупотреблять непереносимыми, но удобными компонентами Java - используйте их только в том случае, когда построить систему иными способами просто невозможно