Главная » Java » Родные методы

0

Их прозвали “чудо-рабочими”,  когда один из них поинтересовался, каким гаечным ключом нужно забивать шуруп в стену

Джордж Браун, конгрессмен, Сан-Бернардино, Калифорния.

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

Уже имеется большой объем работающего программного кода. Проще написать

“прокладку” для этого кода на Java, чем переписывать его заново.

Приложение должно пользоваться системными средствами, отсутствующими в классах Java.

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

Чтобы помочь программисту в подобных ситуациях, Java позволяет реализовывать родные (native) методы на каком-либо из локальных (родных) языков программирования,  обычно C или C++. объявляются следующим образом:

public native void unlock() throws IOException;

Ключевое слово native представляет собой еще один модификатор для объявляемого метода. реализуются на родных языках, поэтому для них не существует программного кода на Java. Тем не менее, они вызываются из Java-программ, как и любые другие методы.

Класс, содержащий родной метод, в соответствии с требованиями безопасности, не может загружаться по сети и выполняться. Более конкретно — классы с родными методами не могут использоваться в аплетах<$Iаплет>.  Даже если вопросы безопасности вас не интересуют, родной код не дает тех гарантий переносимости, которые предоставляет

Java. Любой код на Java, использующий родные методы, должен отдельно переноситься

на каждую целевую платформу.

И все же родные методы могут приносить пользу, особенно если вы будете полагаться на общедоступные библиотеки. Однако код Java, содержащий родные методы, ни в коем случае не может применяться в качестве аплета, запускаемого удаленным пользователем, поскольку аплет должен соответствовать требованиям переносимости и безопасности.

При использовании родных методов также приходится жертвовать защитными ограничениями Java. Так, в традиционных языках, может происходить выход за границы массива и появление неопределенных  значений указателей. Все ограничения на родные методы задаются только тем языком, на котором они написаны.

В этой главе рассказано, как реализовать родной метод на языке C в системах семейства POSIX (к которым относятся, например, Windows NT и большинство реализаций UNIX). Некоторые детали в вашей системе могут отличаться от описанных, а многие среды поддерживают и другие языки кроме C, например, C++. Информацию об этом можно найти в вашей документации. Здесь мы рассматриваем многие важные аспекты

согласования языка C с системой Java компании Sun, версия 1.0.2. Возможно, в вашей локальной среде присутствуют изменения и усовершенствования или используется совершенно иная схема согласования. В частности, описанные здесь способы связывания (binding) родных методов наверняка изменятся в будущих версиях. Но даже с учетом этих обстоятельств, данная глава поможет вам понять некоторые аспекты связывания родных методов, не зависящие от конкретной схемы, принятой в вашей среде.

А.1 Обзор

При стыковке программ на Java с языком C возникают следующие основные проблемы:

Как происходит согласование имен? Полное имя метода в Java имеет вид пакет.класс.метод,  однако в C нет ни пакетов, ни классов. Кроме того, согласование усложняется тем, что в идентификаторах  Java используется кодировка Unicode, а в идентификаторах  С — кодировка ASCII, поэтому необходим дополнительный перевод символов Unicode в символы, разрешенные в C.

Как разрешается проблема различных парадигм вызова? Например, каждый нестатический метод в Java располагает ссылкой this, которая, в сущности, является неявным параметром метода. В C нет ни методов, ни неявных параметров.

Как происходит согласование типов? Родная реализация метода должна обращаться к полям объекта this, и, возможно, методам или полям объектов других типов. Как представить классы Java в языке С?

Как происходит согласование ошибок? Java сообщает о них при помощи исключений, но в C исключения отсутствуют.

Как происходит согласование средств безопасности? Java следит за выходом за границы массивов и преобразованиями  типов, а также осуществляет сборку мусора для борьбы с утечкой памяти и “зависшими” указателями. C и C++ не обладают этими возможностями, так как же производить такие проверки? А что должно происходить в языках типа Pascal, где такая проверка присутствует?

Как происходит согласование работы с памятью? Как программа на языке C

создает объекты Java?

Решая эти и другие проблемы, приходится идти на компромиссы. Например, C и C++ не обладают средствами безопасности Java в работе с массивами, поэтому при согласовании предполагается, что родные методы C и C++ небезопасны в этом отношении. Хотя такой выход и не идеален, он все же выглядит вполне естественно по отношению к C и C++, для которых скорость считается более важной, чем страховка. Например, чтобы реализовать подобную проверку в C или C++, пришлось бы обращаться ко всем элементам массива посредством проверочных функций Java. Такой вариант выглядит неестественно и медленно работает, а поскольку основным доводом в пользу родных методов является скорость, подобный компромисс окажется неверным. К тому же он не будет нормально работать с существующим кодом, в котором используется стандартная для C и C++ парадигма работы с массивами.

Источник: Арнольд К., Гослинг Д. – Язык программирования Java (1997)

По теме:

  • Комментарии