Для чего нужно ключевое слово в Java? - PullRequest
445 голосов
/ 23 мая 2011

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

Для чего используется нативное ключевое слово в Java?

Ответы [ 9 ]

409 голосов

Пример минимального запуска

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 an .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файлы в ART, см. также: Что такое файлы ODEX в Android? Так что, может быть, Java на самом деле также запускается через интерфейс native?

Пример в OpenJDK 8

Давайте найдем, где 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.c # 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

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

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

После расширения набора макросов мы переходим квывод, что это точка определения.

408 голосов
/ 23 мая 2011

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

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

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

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

Смотрите также Спецификация собственного интерфейса Java

323 голосов
/ 23 мая 2011

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

57 голосов
/ 23 мая 2011

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

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

19 голосов
/ 23 мая 2011

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

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

13 голосов
/ 06 апреля 2012

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

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

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

8 голосов
/ 29 ноября 2013

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

6 голосов
/ 19 декабря 2015
  • native - это ключевое слово в Java, оно указывает на платформу.
  • native методы действуют как интерфейс между Java ( JNI ) и другими языками программирования.
6 голосов
/ 23 января 2013

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

...