Javaのnativeキーワードの詳細

4853 ワード

一.Native Methodとは   簡単に言えば、Native Methodはjavaがjavaコード以外のインタフェースを呼び出すインタフェースです.Native Methodは、Cのような非java言語によって実装されるjavaの方法である.この特徴はjava特有ではなく、多くの他のプログラミング言語にはこのメカニズムがあります.例えば、C++では、extern「C」でC++コンパイラにCの関数を呼び出すように伝えることができます.   "A native method is a Java method whose implementation is provided by non-java code."   native methodを定義する場合、インプリメンテーションは提供されません(java interfaceを定義するようなものもあります).なぜなら、インプリメンテーションはjava以外の言語で外部で実装されているからです.次に例を示します.  

package java.lang; 
public class Object { 
  ......
  public final native Class> getClass(); 
  public native int hashCode(); 
  protected native Object clone() throws CloneNotSupportedException; 
  public final native void notify(); 
  public final native void notifyAll(); 
  public final native void wait(long timeout) throws InterruptedException; 
  ......
} 

識別子nativeは、abstractを除く他のjava識別子と連用することができる.これは、nativeがこれらの方法に実装体があることを示唆しているため、これらの実装体はjavaではないが、abstractはこれらの方法に実装体がないことを明らかに示している.nativeが他のjava識別子と連用される場合,その意味は非Native Methodと変わらない.
 native methodメソッドは、非基本タイプを含むjavaタイプを任意に返すことができ、同様に異常制御を行うことができる.これらの方法のインプリメンテーションはjavaの方法と非常に似ている異常を自家製して放出することができる.
native methodの存在は、他のクラスがこれらのローカルメソッドを呼び出すことに何の影響も与えず、実際にこれらのメソッドを呼び出す他のクラスは、ローカルメソッドを呼び出すことさえ知らない.JVMは、ローカルメソッドを呼び出すすべての詳細を制御します.
ローカルメソッドを含むクラスが継承されると、サブクラスはこのローカルメソッドを継承しjava言語でこのメソッドを書き換えることができ(これは少し奇妙に見える)、同じようにローカルメソッドがfianlによって識別されると、継承された後に書き換えることができません.
ローカルメソッドはjvmを効果的に拡張するため、実際には、sunのjavaの同時(マルチスレッド)メカニズム実装では、オペレーティングシステムとの接触点の多くがローカルメソッドを使用しており、javaプログラムがjavaの実行時の限界を超えることができます.ローカルメソッドがあれば、javaプログラムは任意のアプリケーション階層のタスクを行うことができます.
二、使用方法
nativeキーワードは、その修飾方法が、現在のファイルではなく、CやC++などの他の言語で実装されたファイルで対応する実装の元の生態法であることを示している.Java言語自体はオペレーティングシステムの最下位レベルへのアクセスと操作はできませんが、JNIインタフェースで他の言語を呼び出すことで最下位レベルへのアクセスを実現できます.
JNIはJavaネイティブインターフェース(Java Native Interface)であり、Javaソフトウェア開発ツールボックス(Java Software Development Kit,SDK)の一部であるネイティブプログラミングインターフェースである.JNIは、Javaコードが他の言語で作成されたコードとコードライブラリを使用することを許可します.Invocation API(JNIの一部)は、Java仮想マシン(JVM)をネイティブアプリケーションに埋め込むために使用され、プログラマがネイティブコードの内部からJavaコードを呼び出すことを可能にする.
しかし、Java外部への呼び出しは通常他のプラットフォームに移植できず、appletではセキュリティ異常を引き起こす可能性があります.ローカルコードを実装すると、Javaアプリケーションは100%純粋なJavaテストに合格できません.ただし、ローカルコールを実行する必要がある場合は、いくつかのガイドラインを考慮します.
1.ローカルメソッドをすべて1つのクラスにカプセル化します.このクラスは単一のDLLを呼び出します.各ターゲット・オペレーティング・システム・プラットフォームについて、適切なプラットフォーム固有のバージョンのDLLを使用できます.これにより、ローカルコードの影響を最小限に抑えることができ、今後必要な移植問題を考慮するのに役立ちます.
2.ローカルメソッドはできるだけ簡単です.Microsoftを含むサードパーティの実行時のDLLへのローカルメソッドの依存度を最小限に抑えます.ローカルメソッドをできるだけ独立させて、DLLとアプリケーションのロードに必要なコストを最小限に抑えることができます.ランタイムDLLが必要な場合は、アプリケーションとともに提供する必要があります.
JNIの書き方は以下の通りです.
  • a.native宣言付きメソッドを記述するJavaクラス
  • b.javacコマンドを使用してコンパイル作成されたJavaクラス
  • c.java-jni****を使用して.hという接尾辞を持つヘッダファイル
  • を生成する.
  • d.ローカルメソッド
  • を他の言語(C、C++)で実装する.
  • e.ローカルメソッドで記述するファイルを動的リンクライブラリ
  • に生成する.
    JavaでローカルCプログラムを呼び出す簡単な例を次に示します.
    a.HelloWorld.javaクラスの作成
    
    class HelloWorld{
    
    public native void hello();
    
    static{
    System.loadLibrary("hello");
    }
    
    public static void main(String[] args){
    
    new HelloWorld().hello();
    }
    
    }
    

    b.コンパイル
    javac HelloWorld.java
    c..生成.hファイル
    javah -jni HelloWorld
    次のように生成されます.
    
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include 
    /* Header for class HelloWorld */
    
    #ifndef _Included_HelloWorld
    #define _Included_HelloWorld
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
    * Class: HelloWorld
    * Method: hello
    * Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloWorld_hello
    (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    最初のパラメータは、JNIメソッドを呼び出すときに使用されるJNI Environmentポインタです.2番目のパラメータは、このJavaコードでインスタンス化されたJavaオブジェクトHelloWorldのハンドルを指します.その他のパラメータはメソッド自体のパラメータです
    d.c実装
    
    #include 
    #include "HelloWorld.h"
    #include 
    JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv *env,jobject obj){
    printf("Hello World!
    "); return; }

    ここで、最初の行はjni.hファイルを(%JAVA_HOME%includeディレクトリの下に)導入し、JNIEnvとjobjectの定義が入っています.
    e.コンパイルc実装
    ここではWindowsの場合、dllファイルを生成する必要があります.HelloWorldImpl.cフォルダを保存する下に、VCのコンパイラcl成を使用します.
    cl -I%java_home%\include -I%java_home%\include\win32 -LD HelloWorldImp.c -Fehello.dll
    注意:生成されたdllファイル名はオプション-Feの後に配置されます.ここではhelloWorld.javaファイルでloadLibaryのときに使用される名前はhelloです.もちろんここを修正してからそこも修正する必要があります.-I%java_home%\include -I%java_home%includewin 32パラメータに加え、ステップ4でローカルメソッドを記述する際にjni.hファイルが導入されたためです.
    f.プログラムの実行
    JAva HelloWorldでOK!
    以上、Javaのnativeキーワードについて詳しくご紹介しましたので、皆さんの勉強に役立ててください.