ホームページ  >  記事  >  Java  >  Javaでネイティブ修飾子を使用する方法

Javaでネイティブ修飾子を使用する方法

王林
王林転載
2023-04-22 15:46:081796ブラウズ

ネイティブ修飾子の使用

ネイティブは主にメソッドに使用されます

1. ネイティブ メソッドは、Java が非 Java コードを呼び出すためのインターフェイスです。ネイティブ メソッドとは、メソッドの実装が C や C などの非 Java 言語で実装されることを意味します。

2. ネイティブ メソッドを定義する場合、その実装本体は非 Java 言語によって外部で実装されるため、実装本体は提供されません (Java インターフェイスの定義に似ています)。

説明

Java 言語自体はオペレーティング システムの最下層にアクセスして操作することはできませんが、JNI インターフェイスを通じて他の言語を呼び出して最下層へのアクセスを実現できます。

JNI は Java Native Interface であり、Java Software Development Kit (SDK) の一部であるネイティブ プログラミング インターフェイスです。 JNI を使用すると、Java コードで他の言語で記述されたコードおよびコード ライブラリを使用できます。

呼び出し API (JNI の一部) を使用すると、Java 仮想マシン (JVM) をネイティブ アプリケーションに埋め込むことができ、プログラマはネイティブ コード内から Java コードを呼び出すことができます。

JDK ソース コードでは、system.class を例に挙げますが、オペレーティング システムの関連メソッドが呼び出され、その操作は Java で実装されていないため、次のようになります。メソッド

Javaでネイティブ修飾子を使用する方法

#ネイティブに変更されたメソッドの用途

#今日偶然コードを見たら、他の人がメソッドを書いていることに気づきました。このようにjarの中にdllがいくつか入っているのですが、ファイルが変だったのでコードを開いてみると以下のような記述方法がありました。

public native String GSMModemSMSReadAll(String s, int i);
public native String GSMModemGetErrorMsg(String s);
public native boolean GSMModemIsConn(String s);

なかなか面白いと思いますので、インターネットで情報を探してみたところ、良いものが見つかりました。 Java を使用して他の言語を呼び出す別の方法 (以前は知りませんでした -_#)

今日はネイティブ メソッドとは何かについての英語の記事を 2 時間かけて読みました。原文の理解について。

ネイティブ メソッドとは

簡単に言えば、ネイティブ メソッドは、Java が非 Java コードを呼び出すためのインターフェイスです。ネイティブ メソッドは、C などの非 Java 言語で実装される Java メソッドです。この機能は Java に固有のものではありません。他の多くのプログラミング言語にもこのメカニズムがあります。たとえば、C++ では、extern "C" を使用して C++ コンパイラーに C 関数を呼び出すように指示できます。

「ネイティブ メソッドは、実装が非 Java コードによって提供される Java メソッドです。」

ネイティブ メソッドを定義する場合、実装本体は提供されません ( Java インターフェースの定義を好む人もいます)。これは、その実装が非 Java 言語によって外部で実装されるためです。例を以下に示します。

   public class IHaveNatives
    {undefined
      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 以外ですが、抽象は、これらのメソッドに実装がないことを明確に示します。ネイティブが他の Java 識別子とともに使用される場合、その意味は非ネイティブ メソッドと変わりません。たとえば、ネイティブ静的は、クラスのインスタンスを生成せずにこのメソッドを直接呼び出すことができることを示します。これは、たとえば次のような場合に非常に便利です。ネイティブ メソッドを使用して呼び出す場合は、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 プログラムはアプリケーション レベルのタスクを実行できます。

ネイティブ メソッドを使用する理由

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 によって呼び出されます。

JVM はどのようにしてネイティブ メソッドを実行しますか。

クラスが初めて使用されるとき、このクラスのバイトコードはメモリにロードされ、ロードバックされるのは 1 回だけであることがわかっています。クラスのすべてのメソッド記述子のリストは、ロードされたバイトコードの入り口で維持されます。これらのメソッド記述子には、メソッド コードが格納されている場所、そのパラメーター、およびメソッド記述子 (パブリック) などの情報が含まれています。の上。

メソッド記述子にネイティブがある場合、この記述子ブロックはメソッドの実装へのポインターを持ちます。これらの実装は一部の DLL ファイル内にありますが、オペレーティング システムによって Java プログラムのアドレス空間にロードされます。ネイティブ メソッドを持つクラスがロードされるとき、そのクラスに関連付けられた DLL はロードされないため、メソッド実装へのポインタは設定されません。これらの DLL は、ネイティブ メソッドが呼び出されるまでロードされません。これは、java.system.loadLibrary() を呼び出すことによって実現されます。

最後に注意すべきことは、ローカル メソッドを使用するとオーバーヘッドが発生し、Java の利点の多くが失われるということです。選択肢がない場合は、ローカルな方法を使用することもできます

以上がJavaでネイティブ修飾子を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。