web-dev-qa-db-ja.com

Javaのネイティブキーワードは何ですか?

このパズル (これはJavaキーワードのトリビアゲームです)をプレイしているときに、私はnativeキーワードに出会いました。

Javaのネイティブキーワードは何のために使用されますか?

434
whirlwin

メソッドがJNI(Java Native Interface)を使用してネイティブコードで実装されていることを示すために、nativeキーワードがメソッドに適用されます。

315
SLaks

最小限の実行可能な例

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パッケージ/ファイル名のアンダースコアは、C関数名で_1を使用してエスケープする必要があります。 AndroidでのJNI関数の呼び出しアンダースコアを含むパッケージ名

Interpretation

次のことができます。

  • javaの任意のアセンブリコードを使用して、コンパイル済みの動的にロードされたライブラリ(ここではCで記述)を呼び出します。
  • 結果をJavaに戻す

これは次の用途に使用できます。

  • より良いCPUアセンブリ命令を使用して、クリティカルセクションでより高速なコードを記述します(CPUポータブルではありません)
  • 直接システムコールを行います(OSポータブルではありません)

可搬性が低いというトレードオフがあります。

CからJavaを呼び出すこともできますが、最初にCでJVMを作成する必要があります。 C++からJava関数を呼び出す方法は?

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は、共有ライブラリであると言います。これは、ARTのJavaファイルに対応するAOTプリコンパイル済み.dexであると考えています。 ODEXファイルとはAndroidで? 多分Javaもnativeインターフェースを介して実際に実行されますか?

OpenJDK 8の例

Jdk8u60-b27でObject#cloneが定義されている場所を見つけましょう。

native呼び出しで実装されていると結論付けます。

最初に見つけます:

find . -name Object.Java

jdk/src/share/classes/Java/lang/Object.Java#l212

protected native Object clone() throws CloneNotSupportedException;

クローンがすべてのインダイレクションの中でどこにあるのかを見つけるのが難しい部分になりました。私を助けたクエリは:

find . -iname object.c

objectのネイティブメソッドを実装するCまたはC++ファイルを見つけます。 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");

多数のマクロを展開した後、これが定義ポイントであるという結論に達しました。

それはJavaではなく他の言語で実装されるという方法を示しています。 JNI(Java Native Interface)と連携して動作します。

パフォーマンスの重要な部分を記述するためにネイティブメソッドが過去に使用されていましたが、Javaが速くなるにつれてこれはあまり一般的ではありません。ネイティブメソッドが現在必要なのは

  • あなたは他の言語で書かれているJavaからライブラリを呼び出す必要があります。

  • 他の言語(通常はC)からしか到達できないシステムまたはハードウェアリソースにアクセスする必要があります。実際には、実際のコンピュータと対話する多くのシステム機能(ディスクやネットワークIOなど)は、ネイティブコードを呼び出すためにこれを実行することしかできません。

関連項目 Javaネイティブインタフェースの仕様

403
Orhan Cinar

Java言語仕様 /から直接

nativeのメソッドはプラットフォーム依存のコードで実装され、通常C、C++、FORTRAN、またはアセンブリ言語のような別のプログラミング言語で書かれています。 nativeメソッドの本体はセミコロンとしてのみ与えられ、ブロックの代わりに実装が省略されていることを示します。

57
Pops

SLaksが答えたように、nativeキーワードはネイティブコードを呼び出すためのものです。

JavaScriptメソッドを実装するために _ gwt _ でも使用されます。

19
Melv

ネイティブコードを実装する関数は、ネイティブと宣言されています。

JNI(Java Native Interface)は、Java仮想マシン(JVM)で実行されているJavaコードが、ネイティブアプリケーション(ハードウェアおよびオペレーティングシステムプラットフォームに固有のプログラム)およびライブラリで呼び出され、呼び出されることを可能にするプログラミングフレームワークです。 C、C++、アセンブリなどの他の言語.

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

13
Adelin

NATIVEはNon access modifier.itはMETHODにのみ適用できます。メソッドまたはコードのPLATFORM-DEPENDENT含意を示します。

8
Reetika

nativeはJavaのキーワードであり、抽象的なように未実装の構造体(メソッド)を作成するために使用されますが、ネイティブコードのようにプラットフォームに依存し、Javaスタックではなくネイティブスタックから実行されます。

  • nativeはJavaのキーワードで、プラットフォームに依存することを示します。
  • nativeメソッドは、Java( _ jni _ )と他のプログラミング言語との間のインタフェースとして機能します。
6
Premraj