Java - アノテーションとリフレクション (学習ノート)
注釈
Java 組み込みアノテーション
Java は、合計 7 つのアノテーションのセットを定義します。3 つは java.lang に、残りの 4 つは java.lang.annotation にあります。
コードに作用するアノテーションは次のとおりです。
@Override - メソッドがオーバーライド メソッドであるかどうかを確認します。親クラスまたは参照先のインターフェイスにこのメソッドが存在しないことが判明した場合は、コンパイル エラーが報告されます。
@Deprecated - メソッドを非推奨としてマークします。このメソッドを使用すると、コンパイル警告が報告されます。
@SuppressWarnings - アノテーションで宣言された警告を無視するようにコンパイラーに指示します。
他のアノテーションに作用するアノテーション (またはメタ アノテーション) は次のとおりです。
@Retention - このアノテーションがコード内のみにあるのか、クラス ファイルにコンパイルされているのか、実行時にリフレクションを通じてアクセスできるのかなど、このアノテーションがどのように保存されるかを識別します。
@Documented - これらの注釈がユーザー ドキュメントに含まれるかどうかをマークします。
@Target - このアノテーションがどの Java メンバーであるかをマークします。
@Inherited - このアノテーションがどのアノテーション クラスから継承されているかをマークします (デフォルトのアノテーションはどのサブクラスからも継承されません)
Java 7 以降、3 つのアノテーションが追加されました。
@SafeVarargs - Java 7 以降でサポートされており、ジェネリック変数を引数として使用するメソッドまたはコンストラクターの呼び出しからの警告を無視します。
@FunctionalInterface - Java 8 でサポートされ、匿名関数または関数インターフェイスを識別します。
@Repeatable - Java 8 でサポートされており、同じ宣言で注釈を複数回使用できることを示します。
注釈をカスタマイズする方法
@interface カスタム アノテーションを使用すると、java.lang.annotation.Annotation インターフェイスが自動的に継承されます。
分析します:
@ インターフェースはアノテーションの宣言に使用されます。形式: public @ インターフェース アノテーション名 { 定義内容 }
これらの各メソッドは実際に構成パラメーターを宣言します。
メソッドの名前はパラメータの名前です。
戻り値の型はパラメータの型です (戻り値は基本型、Class、String、enum のみです)。
パラメータのデフォルト値はデフォルトで宣言できます。パラメータのメンバーが 1 つだけの場合は、
一般的なパラメータ名は value です。(値が 1 つだけの場合は、その値を削除することもできます)
注釈要素には値が必要です。注釈要素を定義するとき、デフォルト値として空の文字列と 0 を使用することがよくあります。
反射
反省とは何ですか
トピックの導入: Java クラスが (メモリ内で) コンパイルおよび実行されると、対応する .Class ファイル (つまり、Class オブジェクト) が自動的に生成され、クラスのメモリ内には対応する Class オブジェクトが 1 つだけ存在します。この Class オブジェクトは手動で作成することはできません。このオブジェクトには、ちょうどミラーのように、対応するクラスの構造情報全体が含まれており、ミラー上にクラス情報が表示されます。新しいクラスのオブジェクトを通じてメソッドを直接呼び出すのではなく、このクラスのメソッドを使用して、対応するクラスのすべての情報メソッドまたは操作を取得することのみが可能です。
クラスを介してクラスに対応する情報を取得するプロセスは、鏡の前で操作することに似ており、クラスからクラス オブジェクトにマッピングされた情報を通じてクラスを操作するような、マッピング情報によってオントロジーを操作するプロセスがリフレクションです。
クラスを人に例えると、クラスは鏡、コンパイルと実行は外出に例えると、外出するたびに鏡を見ることになり、自分の姿が鏡に映り、鏡を通してあなたに関する情報を得る: 着ている服、名札の名前など。鏡を通して情報を取得するこのプロセスは反射と呼ばれます。あるいは、鏡に向かって髪をブローするとき、髪がなびいている姿を直接見るのではなく、鏡に映る情報を通して髪のなびきを見ているのです。
Class オブジェクトを自動的に生成する型は次のとおりです。
クラス、インターフェイス、[]、[] []、列挙型、注釈、プリミティブ型、void およびその他のデータ型は、ロード時に対応する Class オブジェクトを自動的に生成します。
データ型には Class オブジェクトが 1 つだけあり、ロード時に自動的に作成されます。手動で作成できない Class インスタンスを取得するメソッドは、「Class クラスのインスタンスを取得する 」のみです。
反射の使用
コンセプトの紹介: Java のダイナミズム
概念を導入します:
動的言語: これは、実行時の特定の条件に従ってコード自体の構造を変更できることを意味します。例: Object-C、C#、JavaScript、PHP、Python など。
静的言語: 動的言語に対応して、実行時の構造が不変である言語が静的言語です。Java、C、C++ など。
Java は動的言語ではありませんが、「準動的言語」とも言えます。Java のリフレクション メカニズムを使用して、動的言語と同様の機能を取得できます。リフレクション (リフレクション) は、Java が動的言語としてみなされるための鍵です。リフレクション メカニズムにより、プログラムは実行中に Reflexion API を使用して任意のクラスの内部情報を取得し、任意のクラスの内部プロパティとメソッドを直接操作できます。物体。
リフレクション関連のメイン API > これらのクラス内のメソッドを通じてリフレクションを実装します (クラスに重点を置いています)
java.lang.Class : クラスを表します
java.lang.reflect.Method : クラスのメソッドを表します
java.lang.reflect.Field : クラスのメンバー変数を表します
java.lang.refect.Constructor : クラスのコンストラクターを表します
……
リフレクションを使用する主なアイデア:
リフレクションを通じて対応するクラスのすべての情報、つまり Class オブジェクトを取得し、取得した情報を操作することができます。
取得方法:Classクラスオブジェクトのメソッドが返すMethodオブジェクト、Filedオブジェクト、Constructiorオブジェクトを通じて、対応するクラスの情報、属性、メソッドを取得、呼び出し、操作します(ドキュメントで確認できます)。さらにクラスやフィールドなどのアノテーション情報も取得できます。
リフレクションを通じて (つまり、Class オブジェクトを使用して) 何ができるでしょうか?
Userクラスを例に挙げると、
大前提としてUserクラスのClassオブジェクトが存在する必要があります。例:
//Class オブジェクトを取得する
//Class クラスを通じて User クラスの Class オブジェクトを取得する
Classc1=Class.forName("test04_reflection.User");//"User クラスのパッケージ パス"
Class オブジェクトを使用して User クラスのオブジェクトを作成します (2 つの方法)。
1 つ目は引数のない構造です。
ユーザーのクラス オブジェクト (c1_User) の newInstance() メソッドを使用して、ユーザー オブジェクト user を構築します。
⚠️ 注: 1. クラスにはパラメーターのないコンストラクターが必要です。2. クラスのコンストラクターのアクセス権は十分である必要があります。
2 番目のタイプにはパラメータ構造があります。
クラスを通じてユーザー宣言のパラメーター化されたコンストラクターを取得し、このコンストラクターを通じて新しいユーザーを構築します
Class オブジェクトを通じてメソッドを取得し、User クラス オブジェクトに対してそのメソッド オブジェクトを逆に操作します。
Class オブジェクトを通じて属性を取得し、属性オブジェクトを通じて User クラス オブジェクトに対して逆の操作を行います。
⚠️補足:setAccessible()
Method、Field、および Constructor オブジェクトにはすべて setAccessible() メソッドがあります。
setAccessible の機能は、アクセス セキュリティ チェックの有効化と無効化を切り替えることです。
パラメータ値 true は、反映されたオブジェクトが使用時に Java 言語アクセス チェックをキャンセルする必要があることを示します。
反射効率を向上させます。コード内でリフレクションを使用する必要があり、コードを頻繁に呼び出す必要がある場合は、これを true に設定してください。
他の方法ではアクセスできないプライベート メンバーにアクセスできるようにします
パラメータ値 false は、反映されたオブジェクトが Java 言語アクセス チェックを実装する必要があることを示します。
提案: Class クラス、Method クラス、および Field クラスにカプセル化されたメソッドに関する jdk1.8 ドキュメントをよく理解してください。
反射のメリットとデメリット
利点: 動的なオブジェクトの作成とコンパイルが実現でき、高い柔軟性を示します。
短所:パフォーマンス分析を通じて、リフレクションがパフォーマンスに影響を与えると結論付けることができます。リフレクションの使用は基本的に解釈された操作であり、JVM に何をしたいかを伝えることができ、JVM は必要なことを実行します。このような操作は、同じ操作を直接実行するよりも常に遅くなります。