Java ネイティブ メソッドの詳細な紹介 ネイティブ メソッド
1. ネイティブ メソッドとは
簡単に言えば、ネイティブ メソッドは Java が非 Java コードを呼び出すためのインターフェイスです。ネイティブ メソッドは、C などの非 Java 言語で実装される Java メソッドです。この機能は Java に固有のものではありません。たとえば、C++ では、extern "C" を使用して C++ コンパイラーに C 関数を呼び出すように指示できます。
「ネイティブ メソッドは、実装が非 Java コードによって提供される Java メソッドです。」
ネイティブ メソッドを定義する場合、実装本体は提供されません (Java インターフェイスの定義と似ています)。これは、Java 以外の言語によって外部的に実装されます。例を以下に示します。
public class IHaveNatives { native public void Native1( int x ) ; native static public long Native2() ; native synchronized private float Native3( Object o ) ; native void Native4( int[] ary ) throws Exception ; }
これらのメソッドの宣言は、抽象的なものを除いて、Java コード内で一部の非 Java コードがどのように見えるかを説明します。これは合理的です。ネイティブは、これらのメソッドに実装があることを意味しますが、これらの実装は Java 以外ですが、抽象は、これらのメソッドに実装がないことを明確に示します。ネイティブが他の Java 識別子とともに使用される場合、その意味は非ネイティブ メソッドと変わりません。たとえば、ネイティブ static は、クラスのインスタンスを生成せずにこのメソッドを直接呼び出すことができることを示します。これは、たとえば次のような場合に非常に便利です。ネイティブ メソッドを使用して C クラス ライブラリを呼び出したいとします。上記の 3 番目のメソッドは、ネイティブ同期を使用します。JVM は、このメソッドの実装本体に入る前に同期ロック メカニズムを実行します (Java のマルチスレッドと同様)。
ネイティブ メソッドは、非基本型を含む任意の Java 型を返すことができます。 、例外制御も実行できます。これらのメソッドの実装では、Java メソッドとよく似た例外を作成してスローできます。ネイティブ メソッドが Object や整数配列などの非基本型を受け取ると、メソッドはこれらの非基本型の内部にアクセスできますが、これによりネイティブ メソッドはアクセスしている Java クラスの実装に依存することになります。留意すべき点の 1 つは、ネイティブ メソッドのネイティブ実装ではすべての Java 機能にアクセスできるということですが、これはアクセスする Java 機能の実装に依存し、そうすることは Java 言語での機能を使用するよりもはるかに劣ります。機能は便利で簡単です。
ネイティブ メソッドの存在は、これらのネイティブ メソッドを呼び出す他のクラスには影響しません。実際、これらのメソッドを呼び出す他のクラスは、自分がネイティブ メソッドを呼び出していることさえ知りません。 JVM は、ネイティブ メソッドの呼び出しの詳細をすべて制御します。ローカルメソッドをfinalとして宣言するときの状況に注意する必要があります。 Java で実装されたメソッド本体は、コンパイル時にインライン化されるため効率が向上する場合があります。ただし、ネイティブの Final メソッドでもそのような利点が得られるかどうかは疑問ですが、これはコードの最適化だけの問題であり、機能の実装には影響しません。
ローカル メソッドを含むクラスが継承されると、サブクラスはローカル メソッドを継承し、Java 言語でこのメソッドをオーバーライドできます (これは少し奇妙に思えます) 同様に、ローカル メソッドが fianl でマークされている場合は、次のようになります。継承後にオーバーライドすることはできません。
ローカル メソッドは、jvm を効果的に拡張するため、非常に便利です。実際、私たちが作成した Java コードは、sun の Java 同時実行 (マルチスレッド) メカニズムの実装で、オペレーティング システムとの多くの接続をすでに使用しています。これにより、Java プログラムは Java ランタイムの境界を越えることができます。ネイティブ メソッドを使用すると、Java プログラムはアプリケーション レベルのタスクを実行できます。
2. ネイティブメソッドを使用する理由
Java は非常に便利ですが、一部のレベルのタスクは Java で実装するのが簡単ではない場合や、プログラムの効率を非常に重視する場合に問題が発生します。
Java 環境外の対話:
Java アプリケーションは、Java 外部の環境と対話する必要がある場合があります。これが、ローカル メソッドが存在する主な理由です。Java がオペレーティング システムやハードウェアなどの基盤となるシステムと情報を交換する必要がある状況を考えることができます。ローカル メソッドはまさにそのような通信メカニズムです。ローカル メソッドは非常にシンプルなインターフェイスを提供するため、Java アプリケーションの外部の面倒な詳細を理解する必要はありません。
オペレーティング システムとの対話:
JVM は Java 言語自体とランタイム ライブラリをサポートしており、Java プログラムが依存するプラットフォームであり、インタープリター (バイトコードを解釈する) とローカル コードに接続されたいくつかのライブラリで構成されます。ただし、結局のところ、それは完全なシステムではなく、多くの場合、いくつかの基盤となる (下にある) システムのサポートに依存します。これらの基盤となるシステムは、多くの場合、強力なオペレーティング システムです。ネイティブ メソッドを使用すると、Java を使用して jre と基盤となるシステムの間の対話を実現できます。JVM の一部も C で記述されています。また、Java 言語自体が行うオペレーティング システムの機能を使用したい場合にも使用できます。カプセル化を提供していないため、ネイティブ メソッドを使用する必要もあります。
Sun の Java
Sun のインタプリタは C で実装されており、通常の C と同様に外部と対話できます。 jre のほとんどは Java で実装されており、いくつかのローカル メソッドを通じて外部と対話します。たとえば、クラス java.lang.Thread の setPriority() メソッドは Java で実装されていますが、クラス内のローカル メソッド setPriority0() を呼び出します。このネイティブ メソッドは C で実装され、JVM 内に埋め込まれています。Windows 95 プラットフォームでは、このネイティブ メソッドは最終的に Win32 SetPriority() API を呼び出します。これは、JVM によって直接提供されるローカル メソッドの特定の実装です。多くの場合、ローカル メソッドは外部ダイナミック リンク ライブラリ (外部ダイナミック リンク ライブラリ) によって提供され、JVM によって呼び出されます。
3. JVM はどのようにしてネイティブ メソッドを実行しますか:
クラスが初めて使用されるとき、このクラスのバイトコードはメモリにロードされ、ロードバックされるのは 1 回だけであることがわかっています。クラスのすべてのメソッド記述子のリストは、ロードされたバイトコードのエントリで維持されます。これらのメソッド記述子には、メソッド コードが格納されている場所、メソッド記述子 (パブリック) などの情報が含まれています。の上。
メソッド記述子にネイティブがある場合、この記述子ブロックはメソッドの実装へのポインターを持ちます。これらの実装は一部の DLL ファイル内にありますが、オペレーティング システムによって Java プログラムのアドレス空間にロードされます。ネイティブ メソッドを持つクラスがロードされるとき、そのクラスに関連付けられた DLL はロードされないため、メソッド実装へのポインタは設定されません。これらの DLL は、ネイティブ メソッドが呼び出されるまでロードされません。これは、java.system.loadLibrary() を呼び出すことによって実現されます。
最後に注意すべきことは、ローカル メソッドを使用するとオーバーヘッドが発生し、Java の利点の多くが失われるということです。選択の余地がない場合は、ローカルな方法を使用することもできます。
読んでいただきありがとうございます、お役に立てれば幸いです、このサイトをサポートしていただきありがとうございます!
Java Native Method に関連する詳細な記事については、PHP 中国語 Web サイトに注目してください。