Что такое родное ключевое слово в Java?

Во время игры эта головоломка (это игра с ключевыми словами Java), я наткнулся на ключевое слово native.

Что такое ключевое слово native в Java, которое используется для?

+440
источник поделиться
11 ответов

К методу native применяется метод, указывающий, что метод реализован в собственном коде с использованием JNI (Java Native Interface).

+320
источник

Он отмечает метод, который будет реализован на других языках, а не на Java. Он работает совместно с JNI (Java Native Interface).

В прошлом использовались родные методы для написания критических разделов производительности, но с ускорением Java это стало менее распространенным. Родные методы в настоящее время необходимы, если

  • Вам нужно вызвать библиотеку из Java, написанную на другом языке.

  • Вам необходимо получить доступ к системным или аппаратным ресурсам, доступным только с другого языка (обычно C). Фактически, многие системные функции, которые взаимодействуют с реальным компьютером (например, с дисковым и сетевым IO), могут выполнять только это, потому что они вызывают собственный код.

См. также Спецификация интерфейса Java Native

+406
источник

Минимальный исполняемый пример

Main.java

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

main.C

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

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

Скомпилируйте и запустите:

sudo apt-get install build-essential openjdk-7-jdk
export JAVA_HOME='/usr/lib/jvm/java-7-openjdk-amd64'
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 AMD64. Также работал с Oracle JDK 1.8.0_45.

Пример на GitHub для вас, чтобы играть с.

Символы подчеркивания в именах пакетов/файлов Java должны быть экранированы с помощью _1 в имени функции C, как указано в разделе: Вызов функций JNI в имени пакета Android, содержащем подчеркивание

Интерпретация:

Это позволяет вам:

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

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

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

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

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

Android NDK

Концепция в этом контексте точно такая же, за исключением того, что для ее настройки необходимо использовать шаблон Android.

Официальный репозиторий NDK содержит "канонические" примеры, такие как приложение hello-jni:

unzip .apk с NDK на Android O, вы увидите предварительно скомпилированный .so, соответствующий нативному коду в lib/arm64-v8a/libnative-lib.so.

Подтверждение TODO: более того, file/data/app/com.android.appname-*/oat/arm64/base.odex говорит, что это общая библиотека, которая, как мне кажется, является предварительно скомпилированным .dex AOT, соответствующим файлам Java в АРТ, см. Также: Что такое файлы ODEX в Android? Так может быть, Java на самом деле также работает через native интерфейс?

Пример в OpenJDK 8

Позвольте найти find, где Object#clone определен в jdk8u60-b27.

Мы сделаем вывод, что это реализовано с помощью native вызова.

Сначала мы находим:

find . -name Object.java

что приводит нас к jdk/src/share/classes/java/lang/Object.java # l212:

protected native Object clone() throws CloneNotSupportedException;

Теперь самое сложное - найти место, где клон находится среди всего косвенного. Вопрос, который мне помог, был:

find . -iname object.c

который найдет либо файлы C, либо C++, которые могут реализовывать собственные методы Object. Это приводит нас к jdk/share/native/java/lang/Object.С# l47:

static JNINativeMethod methods[] = {
    ...
    {"clone",       "()Ljava/lang/Object;",   (void *)&JVM_Clone},
};

JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
    (*env)->RegisterNatives(env, cls,
                            methods, sizeof(methods)/sizeof(methods[0]));
}

что приводит нас к символу JVM_Clone:

grep -R JVM_Clone

что приводит нас к точке доступа /src/share/vm/prims/jvm.cpp # l580:

JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
    JVMWrapper("JVM_Clone");

Развернув кучу макросов, мы приходим к выводу, что это точка определения.

+406
источник

Прямо от Спецификация языка Java:

Метод, который native реализуется в платформозависимом коде, обычно написанном на другом языке программирования, таком как C, С++, FORTRAN или язык ассемблера. Тело метода native задается как точка с запятой, указывая на то, что реализация опущена вместо блока.

+57
источник

Как сказал SLaks, ключевое слово native предназначено для вызова собственного кода.

Он также используется GWT для реализации javascript-методов.

+19
источник

которые реализуют собственный код, объявляются native.

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

http://en.wikipedia.org/wiki/Java_Native_Interface

+13
источник

NATIVE - это не модификатор доступа. Он может применяться только к МЕТОДУ. Это указывает на платформо-зависимую реализацию метода или кода.

+8
источник

native - это ключевое слово в java, которое используется для того, чтобы сделать нереализованную структуру (метод) подобной абстрактной, но она будет зависящей от платформы, такой как собственный код и выполняться из собственного стека, а не java-стека.

+6
источник
  • native - это ключевое слово в java, оно указывает на зависимость от платформы.
  • native методы действуют как интерфейс между Java (JNI) и другими языками программирования.
+6
источник

Ключевое слово nativ e используется для объявления метода, который реализуется в зависимом от платформы коде, таком как C или С++. Когда метод помечен как native, он не может иметь тело и должен заканчиваться точкой с запятой. Спецификация Java Native Interface (JNI) регулирует правила и рекомендации для реализации собственных методов, таких как преобразование типов данных между Java и родным приложением.

В следующем примере показан класс с методом, объявленным как native

public class NativeExample {

public native void fastCopyFile(String sourceFile, String destFile);

}

Недостатки собственных методов:

  • Собственные методы хранятся в расширениях .DLL(динамической библиотеки ссылок) в Windows. Файлы DLL зависят от машины. Таким образом, нативные методы не переносятся.

  • Поскольку собственные методы используют машинный код, это может привести к серьезным проблемам безопасности.

+4
источник

Ключевое слово native используется для объявления метода, который реализуется в платформозависимом коде, таком как C или С++. Когда метод помечен как native, он не может иметь тело и должен заканчиваться точкой с запятой. Спецификация Java Native Interface (JNI) регулирует правила и рекомендации для реализации собственных методов, таких как преобразование типов данных между Java и родным приложением.

В следующем примере показан класс с методом, объявленным как native:

public class NativeExample {
    public native void fastCopyFile(String sourceFile, String destFile);
}
+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос