この記事は、主に Java のアノテーションのメカニズムとその原理に関する関連情報を紹介します。この記事が、この部分の内容を理解して習得するのに役立つことを願っています。必要な友人はそれを参照してください。
原理の詳しい説明
アノテーションとは
アノテーションは、一般的な @Override や @Deprecated など、メタデータとも呼ばれます。 アノテーションは、コードを説明するために使用される機能です。パッケージ、クラス、インターフェース、フィールド、メソッドパラメータ、ローカル変数などに注釈を付けることができます。その主な機能は次のとおりです:
ドキュメントを生成し、コード内で識別されたメタデータを通じて javadoc ドキュメントを生成します。
コンパイルチェック。コード内で識別されるメタデータを通じて、コンパイラーはコンパイル中にチェックおよび検証できます。
コード内で識別されたメタデータによるコンパイル時の動的処理 (コードの動的生成など)。
実行時の動的処理。リフレクションインジェクションインスタンスの使用など、コード内で識別されるメタデータによる実行時の動的処理。
一般的なアノテーションは 3 つのカテゴリに分類できます:
最初のカテゴリは、@Override、@Deprecated、@SuppressWarnings などの Java 独自の標準アノテーションで、特定のメソッドのオーバーライドや特定のメソッドのオーバーライドを示すために使用されます。クラスまたはメソッドはそれぞれ廃止されており、無視するよう警告が付けられています。コンパイラは、これらのアノテーションを付けた後でそれらをチェックします。
最初のカテゴリはメタアノテーションです。メタアノテーションは、@Retention、@Target、@Inherited、@Documented などのアノテーションを定義するために使用されるアノテーションであり、アノテーションが保持される段階を示すために使用されます。 @Target はアノテーションの使用範囲を示し、@Inherited はアノテーションを継承できることを示し、@Documented は javadoc ドキュメントを生成するかどうかを示します。
最初のカテゴリはカスタム注釈です。独自のニーズに応じて注釈を定義でき、カスタム注釈にメタ注釈を付けることができます。
アノテーションの使用
アノテーションの使用は非常に簡単です。たとえば、メソッドにアノテーションを付けるだけです。
public class Test { @Override public String tostring() { return "override it"; } }
たとえば、クラスにアノテーションを付けます。 :
@Deprecated public class Test { }
そのため、Java の組み込みアノテーションを直接使用できますが、多くの場合、いくつかのアノテーションを自分で定義する必要があります。たとえば、一般的な Spring はオブジェクト間の依存関係を管理するために多数のアノテーションを使用します。独自のアノテーションを定義する方法を見てみましょう。そのようなアノテーションを実装してみましょう。@Test を通じて特定のクラスに文字列を注入し、@TestMethod を通じて特定のメソッドに文字列を注入します。
①Testアノテーションを作成し、クラスに作用するように宣言し、実行時まで保持します。デフォルト値はdefaultです。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Test { String value() default "default"; }
②TestMethod アノテーションを作成し、メソッドに作用するように宣言し、実行時まで保持します。
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface TestMethod { String value(); }
③テストクラスは実行後にdefaultとtomcat-methodの2つの文字列を出力します。 @Testは値を渡さないためデフォルト値が出力され、@TestMethodは注入された文字列を出力します。
@Test() public class AnnotationTest { @TestMethod("tomcat-method") public void test(){ } public static void main(String[] args){ Test t = AnnotationTest.class.getAnnotation(Test.class); System.out.println(t.value()); TestMethod tm = null; try { tm = AnnotationTest.class.getDeclaredMethod("test",null).getAnnotation(TestMethod.class); } catch (Exception e) { e.printStackTrace(); } System.out.println(tm.value()); } }
アノテーションの原則
前回の記事では、Java の組み込みアノテーションの使用方法とアノテーションのカスタマイズ方法を紹介しました。次に、アノテーションの実装の原則とアノテーションの付け方を見てみましょう。より大規模な Java システムのサポート。上記のカスタム アノテーションの例に戻りましょう。次のように、AnnotationTest クラスにアノテーションが付けられている場合、アノテーション宣言の値は AnnotationTest.class.getAnnotation(Test.class) を通じて取得できます。上記の文を見ると、クラス構造から Test アノテーションを取得していることがわかります。そのため、ある時点でアノテーションがクラス構造に追加されているはずです。
@Test("test") public class AnnotationTest { public void test(){ } }
Java ソース コードからクラス バイトコードへの変換はコンパイラによって行われ、コンパイラによって Java ソース コードが解析され、アノテーション シンボルもコンパイラによって処理されます。 JVM 仕様によれば、クラス ファイル構造は厳密に順序付けされた形式であり、クラス構造に情報を追加する唯一の方法は、クラス構造の属性に保存することです。クラス、フィールド、およびメソッドには、クラス構造内に独自のテーブル構造があり、それぞれに独自の属性があることがわかります。また、アノテーションの場合、それらのアクションの範囲は、クラスまたはフィールドに対して異なる場合があります。またはメソッドを使用すると、コンパイラはクラス、フィールド、またはメソッドのプロパティにアノテーション情報を保存します。
AnnotationTest クラスがコンパイルされると、対応する AnnotationTest.class ファイルに RuntimeVisibleAnnotations 属性が含まれるようになります。このアノテーションはクラスに適用されるため、この属性はクラスの属性セットに追加されます。つまり、Test アノテーションのキーと値のペア value=test が記録されます。 JVM が AnnotationTest.class ファイルのバイトコードをロードすると、RuntimeVisibleAnnotations 属性値が AnnotationTest の Class オブジェクトに保存されるため、Test アノテーション オブジェクトは AnnotationTest.class.getAnnotation(Test.class) を通じて取得でき、次に The Test を通じて取得できます。アノテーションオブジェクトはTestで属性値を取得します。
ここで質問があるかもしれませんが、Test アノテーション オブジェクトとは何ですか?実際、コンパイルされたアノテーションの本質は Annotation インターフェイスを継承するインターフェイスであるため、@Test は実際には「パブリック インターフェイス Test extends Annotation」になります。これを AnnotationTest.class.getAnnotation(Test.class) を通じて呼び出すと、JDK は次のようになります。動的プロキシを通じて生成する Test インターフェイスを実装し、このオブジェクトに RuntimeVisibleAnnotations 属性値を設定するオブジェクト。このオブジェクトは Test アノテーション オブジェクトであり、その value() メソッドを通じてアノテーション値を取得できます。
Java アノテーション実装メカニズムの全体的なプロセスは上に示したとおりであり、その実装にはコンパイラーと JVM の協力が必要です。
以上がJava のアノテーションのメカニズムと原則の詳細な例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。