このパズル (これはJavaキーワードのトリビアゲームです)をプレイしているときに、私はnative
キーワードに出会いました。
Javaのネイティブキーワードは何のために使用されますか?
メソッドがJNI(Java Native Interface)を使用してネイティブコードで実装されていることを示すために、native
キーワードがメソッドに適用されます。
最小限の実行可能な例
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:
次のことができます。
これは次の用途に使用できます。
可搬性が低いというトレードオフがあります。
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ネイティブインタフェースの仕様
Java言語仕様 /から直接
native
のメソッドはプラットフォーム依存のコードで実装され、通常C、C++、FORTRAN、またはアセンブリ言語のような別のプログラミング言語で書かれています。native
メソッドの本体はセミコロンとしてのみ与えられ、ブロックの代わりに実装が省略されていることを示します。
SLaksが答えたように、native
キーワードはネイティブコードを呼び出すためのものです。
JavaScriptメソッドを実装するために _ gwt _ でも使用されます。
ネイティブコードを実装する関数は、ネイティブと宣言されています。
JNI(Java Native Interface)は、Java仮想マシン(JVM)で実行されているJavaコードが、ネイティブアプリケーション(ハードウェアおよびオペレーティングシステムプラットフォームに固有のプログラム)およびライブラリで呼び出され、呼び出されることを可能にするプログラミングフレームワークです。 C、C++、アセンブリなどの他の言語.
NATIVEはNon access modifier.itはMETHODにのみ適用できます。メソッドまたはコードのPLATFORM-DEPENDENT含意を示します。
nativeはJavaのキーワードであり、抽象的なように未実装の構造体(メソッド)を作成するために使用されますが、ネイティブコードのようにプラットフォームに依存し、Javaスタックではなくネイティブスタックから実行されます。
native
はJavaのキーワードで、プラットフォームに依存することを示します。native
メソッドは、Java( _ jni _ )と他のプログラミング言語との間のインタフェースとして機能します。