Do czego służy natywne słowo kluczowe w Javie?

Podczas gry w tę zagadkę (jest to gra ciekawostki ze słowem kluczowym Java) natknąłem się na słowo kluczowe native.

Do czego służy natywne słowo kluczowe w Javie?

Author: Hamedz, 2011-05-23

10 answers

Słowo kluczowe native jest stosowane do metody, aby wskazać, że metoda jest zaimplementowana w kodzie natywnym przy użyciu JNI (Java Native Interface).

 351
Author: SLaks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-05 06:05:07

Minimal runnable przykład

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;
}

Skompiluj i uruchom:

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

Wyjście:

4

Testowane na Ubuntu 14.04 AMD64. Pracował również z Oracle JDK 1.8.0_45.

Przykład na GitHub do zabawy.

Podkreślniki w nazwach pakietów / plików Java muszą być zabezpieczone znakiem _1 w nazwie funkcji C, jak wspomniano w: wywołanie funkcji JNI w nazwie pakietu Androida zawierającego podkreślenie

Interpretacja

native pozwala na:

  • wywołanie skompilowanej dynamicznie załadowanej biblioteki (tutaj napisanej w języku C) z dowolnym kodem asemblera z Javy
  • i uzyskać wyniki z powrotem do Java

To może być użyte do:

    [50]}pisz szybszy kod na krytycznej sekcji z lepszymi instrukcjami montażu procesora (nie CPU portable)
  • wykonuj bezpośrednie wywołania systemowe (nie Przenośne)

Z kompromis z niższej przenośności.

Możliwe jest również wywoływanie Javy z C, ale najpierw musisz utworzyć JVM w C: jak wywoływać funkcje Javy z C++?

Analogiczne natywne API rozszerzeń są również obecne w wielu innych "językach VM" z tych samych powodów, np., węzeł.js, Ruby .

Android NDK

Koncepcja jest dokładnie taka sama w tym kontekście, z tym, że trzeba używać Androida Płyta kotłowa do Ustawienia.

Oficjalne repozytorium NDK zawiera "kanoniczne" przykłady, takie jak aplikacja hello-jni:]}

W tobie unzip an .apk z NDK na Androida O, możesz zobaczyć wstępnie skompilowany .so, który odpowiada kodowi natywnemu pod lib/arm64-v8a/libnative-lib.so.

TODO confirm: ponadto, file /data/app/com.android.appname-*/oat/arm64/base.odex, mówi, że jest to biblioteka współdzielona, która moim zdaniem jest prekompilowana przez AOT .dex odpowiadający plikom Java w ART, Zobacz także: czym są pliki ODEX w Androidzie? więc może Java jest tak naprawdę uruchamiana przez interfejs native?

Przykład w OpenJDK 8

Znajdźmy gdzie Object#clone jest zdefiniowany w jdk8u60-b27.

Wyciągniemy wniosek, że jest on zaimplementowany za pomocą native wywołania.

Najpierw znajdujemy:

find . -name Object.java

Co prowadzi nas do jdk/src / share/classes/java/Lang / Object.java#l212 :

protected native Object clone() throws CloneNotSupportedException;

Teraz najtrudniejsza część, znalezienie miejsca, w którym znajduje się klon pośród wszystkich indyrecji. Pytanie, które mi pomogło, brzmiało:

find . -iname object.c

Który znajdowałby pliki C lub C++, które mogłyby implementować natywne metody obiektu. Prowadzi nas do 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]));
}

Co prowadzi do symbolu JVM_Clone:

grep -R JVM_Clone

Co prowadzi nas do hotspot / src/share/vm/prims / jvm.cpp#l580 :

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

Po rozwinięciu kilku makr, dochodzimy do wniosku, że jest to punkt definicji.

 467
Author: Ciro Santilli TRUMP BAN IS BAD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-10 11:24:46

Oznacza metodę, która będzie zaimplementowana w innych językach, a nie w Javie. Współpracuje z JNI (Java Native Interface).

Natywne metody były używane w przeszłości do pisania sekcji krytycznych dla wydajności, ale z Java coraz szybsze jest to obecnie mniej powszechne. Natywne metody są obecnie potrzebne, gdy

  • Musisz wywołać bibliotekę z Javy, która jest napisana w innym języku.

  • Musisz uzyskać dostęp do zasobów systemowych lub sprzętowych, które są tylko osiągalny z innego języka (typowo C). W rzeczywistości wiele funkcji systemowych, które współdziałają z rzeczywistym komputerem (na przykład dysk i sieć IO), może to zrobić tylko dlatego, że wywołują kod natywny.

Zobacz Java Native Interface Specification

 425
Author: Orhan Cinar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-28 09:34:10

Prosto z specyfikacji języka Java:

Metoda native jest zaimplementowana w kodzie zależnym od platformy, zazwyczaj napisanym w innym języku programowania, takim jak C, C++, FORTRAN lub assembly language. Ciało metody native jest podane tylko jako średnik, co oznacza, że implementacja jest pominięta, zamiast bloku.

 59
Author: Pops,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-23 18:51:00

Jak odpowiedział SLaks, słowo kluczowe native służy do wywołania kodu natywnego.

Jest również używany przez GWT do implementacji metod javascript.

 19
Author: Melv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-23 18:40:15

Funkcje implementujące natywny kod są deklarowane jako natywne.

Java Native Interface (JNI) - framework programistyczny, który umożliwia uruchamianie kodu Javy na maszynie wirtualnej Javy (JVM) i wywoływanie go przez natywne aplikacje (programy specyficzne dla platformy sprzętowej i systemu operacyjnego) oraz biblioteki napisane w innych językach, takich jak C, C++ i assembly.

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

 13
Author: Adelin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-06 07:12:55

NATIVE is Non access modifier.it może być stosowany tylko do metody. Wskazuje implementację metody lub kodu zależną od platformy.

 8
Author: Reetika,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-21 07:29:10

Native jest słowem kluczowym w Javie, które jest używane do tworzenia struktury(metody) nie implementowanej jako abstrakcyjna, ale byłaby zależna od platformy, takiej jak kod natywny i wykonywałaby ze stosu natywnego, a nie stosu Javy.

 6
Author: Sarfaraz Ahamad Shaikh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 16:16:59
  • native jest słowem kluczowym w języku java, oznacza zależne od platformy.
  • native metody działają jako interfejs pomiędzy Javą(JNI) i innymi językami programowania.
 6
Author: Premraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-20 09:09:55

Metoda Java native zapewnia mechanizm, w którym kod Java wywołuje kod natywny systemu operacyjnego, zarówno ze względów funkcjonalnych, jak i wydajnościowych.

Przykład:

606  public native int availableProcessors();
617  public native long freeMemory();
630  public native long totalMemory();
641  public native long maxMemory();
664  public native void gc();

W odpowiednim pliku Runtime.class w OpenJDK, znajdującym się w JAVA_HOME/jmods/java.base.jmod/classes/java/lang/Runtime.class, zawiera te metody i otagował je ACC_NATIVE (0x0100), i te metody nie zawierają kodu atrybut , co oznacza, że te metody nie mają żadnej rzeczywistej logiki kodowania w pliku Runtime.class:

  • metoda 13 availableProcessors: oznaczona jako natywna i bez atrybutu kodu
  • metoda 14 freeMemory: oznaczona jako natywna i bez atrybutu kodu
  • metoda 15 totalMemory: oznaczona jako natywna i bez atrybutu kodu
  • metoda 16 maxMemory: oznaczona jako natywna i bez atrybutu kodu
  • Method 17 gc: tagged as native and no Code atrybut

Tutaj wpisz opis obrazka

W rzeczywistości logika kodowania znajduje się w odpowiednim uruchomieniu .c plik:

42  #include "java_lang_Runtime.h"
43
44  JNIEXPORT jlong JNICALL
45  Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject this)
46  {
47      return JVM_FreeMemory();
48  }
49
50  JNIEXPORT jlong JNICALL
51  Java_java_lang_Runtime_totalMemory(JNIEnv *env, jobject this)
52  {
53      return JVM_TotalMemory();
54  }
55
56  JNIEXPORT jlong JNICALL
57  Java_java_lang_Runtime_maxMemory(JNIEnv *env, jobject this)
58  {
59      return JVM_MaxMemory();
60  }
61
62  JNIEXPORT void JNICALL
63  Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
64  {
65      JVM_GC();
66  }
67  
68  JNIEXPORT jint JNICALL
69  Java_java_lang_Runtime_availableProcessors(JNIEnv *env, jobject this)
70  {
71      return JVM_ActiveProcessorCount();
72  }

I te C kodowanie jest kompilowane do pliku libjava.so (Linux) lub libjava.dll (Windows), znajdującego się pod JAVA_HOME/jmods/java.base.jmod/lib/libjava.so:

Tutaj wpisz opis obrazka

Tutaj wpisz opis obrazka

Odniesienie

 3
Author: Happy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-06 06:59:24