Использование родного языка Java

Может кто-нибудь объяснить whys и wherefores для использования родного ключевого слова в Java?

Ответ 1

По моему опыту, недостатки использования собственных библиотек кода значительны:

  • JNI/JNA имеют тенденцию дестабилизировать JVM, особенно если вы попытаетесь сделать что-то сложное. Если ваш собственный код неправильно управляет встроенной памятью кода, есть вероятность, что вы столкнетесь с JVM. Если ваш собственный код не является реентерабельным и получает вызов из более чем одной ветки Java, плохие вещи будут происходить... спорадически. И так далее.

  • Java с собственным кодом сложнее отлаживать, чем чистая Java или чистая C/С++.

  • Нативный код может вносить существенные зависимости/проблемы платформы для другого независимого от платформы Java-приложения.

  • Внутренний код требует отдельной структуры сборки, и это может также иметь проблемы с платформой/переносимостью.

Вообще говоря, вы не получаете большой (если таковой) дополнительной производительности, используя собственный код. Хотя вы можете подумать, что ваш C/С++ будет более реалистичным, чем Java, JIT-компилятор делает довольно хорошую работу по оптимизации в эти дни, и вам нужно учитывать затраты на производительность для создания вызовов JNI и других взаимодействий через границу JNI.

Как правило, вы должны рассматривать JNI/JNA как "последнее средство". Если есть какой-либо другой способ решения проблемы, этот способ, вероятно, лучше.

Ответ 2

  • У вас может быть библиотека, отличная от Java, по каким-либо причинам вы должны использовать в своем проекте Java
  • Возможно, вам понадобится интегрировать какое-то старое или редко используемое оборудование и нужно реализовать интерфейс, который может быть намного проще в C/С++

Если вы хотите решить проблему производительности с помощью собственного кода, чем 99,5% вероятность, что это неправильный подход; -)

Ответ 3

Может кто-нибудь объяснить whys и wherefores для использования родного ключевого слова в Java?

Как только вы увидите небольшой пример, становится ясно:

Main.java

public class Main {
    public native int intMethod(int i);
    public static void main(String[] args) {
        System.loadLibrary("Main");
        System.out.println(new Main().intMethod(2));
    }
}

main.c

#include <jni.h>
#include "Main.h"

JNIEXPORT jint JNICALL Java_Main_intMethod(
    JNIEnv *env, jobject obj, jint i) {
  return i * i;
}

Скомпилировать и запустить:

javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
  -I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main

Выход

4

Протестировано на Ubuntu 14.04 с Oracle JDK 1.8.0_45.

Итак, понятно, что он позволяет вам:

  • вызов скомпилированной динамически загруженной библиотеки (здесь написанной на C) с произвольным кодом сборки из Java
  • и вернуть результаты в Java

Это можно использовать для:

  • написать более быстрый код в критическом разделе с более точными инструкциями по сборке процессора (не ЦП)
  • делать прямые системные вызовы (не переносимые ОС)

с компромиссом более низкой переносимости.

Вы также можете вызвать Java из C, но сначала вы должны создать JVM в C: Как вызвать функции Java из С++?

Пример для GitHub для вас.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: часть этого ответа получена из моего более раннего ответа. Я считаю, что я прямо ответил на вопрос ОП в каждом.

Ответ 4

Как веб-разработчик, вы, скорее всего, столкнетесь с native, если используете Google Web Toolkit. В этой структуре вы по существу записываете Java-код, который затем скомпилируется в Javascript, который может работать в браузере. В GWT ключевое слово native используется для совершения вызовов на "собственный" Javascript-код.

Термин для поиска - JSNI.

Ответ 5

  • производительности
  • более тесная интеграция с родной средой
  • необходимо использовать собственную библиотеку с уникальными функциями

Примеры: JAI (обработка изображений), Java 3D (OpenGL), JDIC (интеграция с рабочим столом)

Ответ 6

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

Иногда, однако, вам нужно что-то делать в своей программе, которая очень специфична для определенной операционной системы, и, возможно, не будет чистого Java-способа делать то, что вам нужно делать; или вам может потребоваться вызвать существующую библиотеку, отличную от Java. Платформа Java предоставляет JNI (Java Native Interface) как способ вызова кода операционной системы.

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

Ответ 7

Вот некоторые цитаты из Effective Java 2nd Edition, пункт 54: разумно используйте собственные методы:

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

Допустимо использовать собственные методы для доступа к средствам на платформе, но по мере созревания платформы Java она предоставляет mroe и другие функции, ранее найденные только на платформах хоста. [...] Не рекомендуется использовать собственные методы для повышения производительности [...]

Использование собственных методов имеет серьезные недостатки. Поскольку родные языки небезопасны, приложения, использующие собственные методы, больше не защищены от ошибок, связанных с повреждением памяти. Поскольку родные языки зависят от платформы, приложения, использующие собственные методы, гораздо менее переносимы. Приложения, использующие собственный код, трудно отлаживать. Существует фиксированная стоимость, связанная с входом и выводом из собственного кода, поэтому собственные методы могут снизить производительность, если они выполняют лишь небольшой объем работы. Наконец, нативные методы требуют "кода клея", который трудно читать и утомительно писать.

Весь предмет содержит более подробные объяснения по вопросам. Наряду со всей книгой настоятельно рекомендуется.

См. также

Ответ 8

Класс виджета GWT HTML имеет этот камень для довольно-печатной. Не слишком полезно, когда вы хотите проверить код красивого принтера: (

    /**
    * All of the markup and content within a given element.
    */
        public final native void setInnerHTML(String html) /*-{
        this.innerHTML = html || '';
    }-*/;