Java アノテーション、メタ アノテーション、カスタム アノテーションの使用
Java アノテーション
JDK5から、Javaはメタデータ、つまり注釈のサポートを追加しました. 注釈と注釈には特定の違いがあります.注釈はコード内の特別なタグとして理解できます. これらのタグはコンパイル中、クラスのロード中および実行時に読み取ることができます. 、および対応する処理を実行します。注釈を使用すると、開発者は元のコードやロジックを変更することなく、補足情報をソース コードに埋め込むことができます。
アノテーション (Annotation) は、クラス/メソッドの拡張されたテンプレートと見なすことができます. 各クラス/メソッドは、アノテーション クラス内のルールに従って、クラス/メソッドに異なるパラメーターをアノテーションし、使用される場所で異なるパラメーターを取得できます.クラス/メソッドで注釈が付けられたパラメーターと値
基本注釈
Java は 5 つの基本的な注釈を提供します。@Override,@Deprecated,@SuppressWarnings,@SafeVarargs,@FunctionalInterface
1.@オーバーライド
親クラスのオーバーライド メソッドを制限する: @Override、サブクラスが親クラスのメソッドをオーバーライドする場合、サブクラスはこのアノテーションを追加でき、サブクラスが親クラスのメソッドをオーバーライドする場合、サブクラスはこのアノテーションを追加できます。
2.@非推奨
廃止のマーク: @Deprecated。この注釈は、プログラム要素のクラス、メソッドなどが古いことを示すために使用され、他のプログラムが古いクラスやメソッドを使用している場合、コンパイラは警告を発します ( xxx )
3.@SuppressWarnings
コンパイラの警告を抑制: @SuppressWarnings、この注釈によって変更された要素、および要素のすべてのサブ要素は、コンパイラの警告の表示をキャンセルします
4.@SafeVarargs
@SafeVarargs による「ヒープ汚染」警告
5.@機能インターフェース
機能インターフェースと @Functionallinterface の場合、このアノテーションにより、インターフェースに抽象メソッドが 1 つしかないことが保証されます。これはインターフェースのみを変更できることに注意してください。
機能インターフェース: インターフェースに抽象メソッドが 1 つしかない場合 (複数のデフォルト メソッドまたは複数の静的メソッドを含めることができます)、
インターフェース本体で宣言できるのは定数フィールドと抽象メソッドのみであり、それらは public、static、および public として暗黙的に宣言されます。そしてファイナル。
インターフェイスには、プライベート メソッドまたは変数を含めることはできません。
Java が提供するメタ アノテーション
メタ注釈の役割は、他の注釈に注釈を付けて、他の注釈タイプの説明を提供することです。
1.@保持
@Retention は、アノテーションの定義を変更するために使用されます。その機能は、変更されたアノテーションを保存できる期間 (つまり、アノテーションのライフサイクル) です。このアノテーションは、パラメーターを使用する必要があります (パラメーターは、SOURCE、CLASS 、ランタイム)。
@Retention ソースコード:
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
@Retention アノテーション パラメータは、次のように列挙型です。
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
RetentionPolicy.CLASS (デフォルト値) コンパイラはクラス ファイルに注釈を記録します。Java プログラムを実行すると、JVM はアノテーション情報を取得できません。
RetentionPolicy.RUNTIME コンパイラは、この注釈をクラス ファイルに記録します。Java プログラムを実行すると、JVM はアノテーション情報を取得でき、プログラムはリフレクションによってアノテーション情報を取得できます。
RetentionPolicy.SOURCE 注釈はソース コードにのみ保存され、コンパイラは注釈を直接破棄します。
2.@ターゲット
@Target アノテーションは、アノテーションの使用範囲、つまり、アノテーションを使用できる場所 (TYPE クラス|インターフェース、FIELD フィールド、METHOD メソッド、PARAMETER パラメーター...) を記述するために使用され、その使用範囲も列挙配列 ElementType[] value();
。
@Target アノテーションはソース コードを定義します。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
@Target アノテーションの ElementType[] パラメータ配列ソース コード:
package java.lang.annotation;
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE
}
価値 | アノテーション使用範囲 |
---|---|
方法 | メソッドで使用できます |
タイプ | クラスまたはインターフェースで使用可能 |
ANNOTATION_TYPE | 注釈型 (@interface によって変更された型) で使用できます |
コンストラクタ | コンストラクタで使用可能 |
分野 | フィールドで入手可能 |
ローカル変数 | ローカル変数で使用できます |
パッケージ | Javaファイルのパッケージ情報を記録するために使用 |
パラメータ | パラメータで使用できます |
3.@文書化
@Documented 注釈は、変更された注釈クラスが javadoc ツールによってドキュメントに抽出されることを指定するために使用されます。注釈クラスを定義するときにこの注釈の変更が使用される場合、この注釈で装飾されたすべてのプログラマおよび API ドキュメントには、注釈の説明が含まれます。 .
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
4.@継承
@Inherited アノテーションは、それによって変更されたアノテーションが継承されることを指定します。つまり、サブクラスは親クラスのアノテーションを継承できます。
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
カスタム注釈
カスタム アノテーションを@interface
定義する必要があります。@interface カスタム アノテーションを使用すると、それらは自動的に継承されますjava.lang.annotation.Annotation接口
。
カスタム コメント形式:
权限修饰符 @interface 注解名{
// 定义内容
String value() default "";
// 参数类型 参数名 默认值 ;
.....
}
- @interface はアノテーションの宣言に使用されます
- 上記は、この注釈が文字列型パラメーターを提供する必要があり、そのデフォルト値が空の文字列であること
String value();
を示していますdefault ""
- value() はパラメータの名前です
- 文字列はパラメーターの必須の型であり、パラメーターの型は基本型 (クラス、文字列、列挙型) のみにすることができます
- パラメータのデフォルト値はデフォルトで宣言できます
- パラメータメンバーが1つしかない場合、一般的なパラメータ名は値です(もちろん、パラメータ名はカスタマイズできます。それは単なる習慣です)
- 注釈要素には値が必要です。注釈要素を定義する場合、空の文字列がよく使用され、デフォルト値は 0 です。
カスタム注釈の使用
package com.robin.annotation;
import java.lang.annotation.*;
import java.lang.reflect.Method;
// 使用自定义的注解 传入参数 robin 和 23
@MyAnnotation(value = "robin", age = 23)
public class AnnoTest01 {
// 使用自定义的注解 传入参数 知更鸟 和 18
@MyAnnotation(value = "知更鸟",age = 18)
public void test01() {
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
// 通过反射来获取当前Class类对象中的注解
Class<?> cls = Class.forName("com.robin.annotation.AnnoTest01");// 获取AnnoTest01的Class类对象
MyAnnotation annotation1 = cls.getAnnotation(MyAnnotation.class);// 获取当前Class类对象的注解信息
System.out.println("作用在类上的注解:"+annotation1);// @com.robin.annotation.MyAnnotation(value=robin, age=23)
// 通过Class类对象获取Method对象
Method test01 = cls.getMethod("test01");
MyAnnotation annotation2 = test01.getAnnotation(MyAnnotation.class);
System.out.println("作用在method上的注解:"+annotation2);// @com.robin.annotation.MyAnnotation(value=知更鸟, age=18)
}
}
// 自定义内部类注解
@Target({
ElementType.TYPE, ElementType.METHOD})// 作用范围为类和方法上面
@Retention(RetentionPolicy.RUNTIME)// 此注解的生命周期为RUNTIME
@interface MyAnnotation {
String value() default "";
int age() default 0;
}
皆さん、明けましておめでとうございます!