カスタム注釈 (1)


アノテーションは JDK1.5 で導入された機能で、コードを説明するために使用され、パッケージ、クラス、インターフェイス、フィールド、メソッド パラメータ、ローカル変数などを次の 3 つのカテゴリにマークできます。
, @Override (メソッドをオーバーライドする)、@Deprecated (クラスまたはメソッドが廃止されたことを示す)、@SuppressWarnings (無視される警告を示す) など 2. 1 つのタイプはメタ アノテーションで、アノテーションのアノテーションを定義するために使用されます
。 、 @Retention (アノテーションが保持される段階を示す)、@Target (アノテーションの範囲を示す)、@Inherited (アノテーションが継承できることを示す)、@Documented (Javadoc ドキュメントを生成するかどうかを示す) を含む 3.カスタム注釈はニーズに応じてカスタマイズできます
定義注釈

機能:
1. ドキュメントを生成し、コードで特定されたメタデータを通じて javadoc ドキュメントを生成します。
2. コンパイル検査。コードで特定されたメタデータを通じてコン​​パイル中にコンパイラにチェックおよび検証させます
。 3. コンパイル時の動的処理。コンパイル時にコードを渡します。時間 コードで表されるメタデータの動的処理 (コードの動的生成など)
4. 実行時の動的処理、実行時のコードで表されるメタデータの動的処理 (リフレクション インジェクション インスタンスの使用など)

Android のカスタム アノテーションは
メタ アノテーションを使用してカスタム アノテーションを定義します

メタアノテーション 説明する
@目標 注釈が表示される場所を示します。ElementType 列挙型です
@保持 このアノテーションの有効期間
@書類 注釈が javadoc などのツールで文書化できることを示します
@遺伝性の サブクラスがアノテーションを継承できるようにするかどうか。デフォルトは false です。

@Target ElementType タイプの説明:
ElementType.TYPE インターフェイス、クラス、列挙、注釈
ElementType.FIELD フィールド
ElementType.METHOD メソッド
ElementType.PARAMETER メソッド パラメーター
ElementType.CONSTRUCTOR コンストラクター
ElementType.LOCAL_VARIABLE ローカル変数
ElementType.ANNOTATION_TYPE 注釈
ElementType.PACKAGE パッケージ

@Retention RetentionPolicy タイプの説明:
RetentionPolicy.SOURCE アノテーションはソース ファイルにのみ保持されます。Java ファイルがクラス ファイルにコンパイルされると、アノテーションは破棄されます。RetentionPolicy.CLASS アノテーションはクラス ファイルに保持されますが
、 jvm がクラス ファイルをロードすると破棄されます。これはデフォルトのライフ サイクルです
。RetentionPolicy.RUNTIME アノテーションはクラス ファイルに保存されるだけでなく、jvm がクラス ファイルをロードした後も存在します。

アノテーションの宣言:
上記のように @Retention メタアノテーションを使用してアノテーションのタイミングを決定し、
@Target を使用してアノテーションが適用される対象を決定します。

カスタム アノテーションの分類:
**実行時アノテーション、**コード実行プロセス中にリフレクション メカニズムを通じてカスタム アノテーションを検索し、対応する処理を実行します
**コンパイル時アノテーション、**コンパイル プロセスで javac を使用する アノテーション プロセッサカスタム注釈をスキャンし、注釈を処理して必要なファイル (通常は Java ファイル) を生成します。

コンパイル時のアノテーション:
1. 宣言アノテーション
2. 解析アノテーション

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindView {
    
    
    int value();
}

コンパイル時にアノテーションを分析するには、アノテーション分析プロセッサを自分で実装する必要があります。プロセッサによって行われる作業に注意してください。これは、コードのコンパイル プロセス中に指定するアノテーションを見つけて、独自の特定のロジックを追加することです (通常は Java ファイルを生成します)。 注: モジュールを実装するには、Java である必要があります
。 -library (Java ライブラリは Processor AbstractProcessor を継承できるため)
アノテーション プロセッサの登録を容易にするために、goole は登録用の登録プロセッサ ライブラリ @AutoService(Processor.class) を提供します。

依存関係を追加する

dependencies {
    
    
    implementation 'com.google.auto.service:auto-service:1.0-rc2'
}
@AutoService(Process.class)
public class BindViewProcessor extends AbstractProcessor {
    
    
private Elements elements;
private Messager messager;
private Filer filer;
private Types types;

    /**
     * 注解处理器的核心方法,在这里来处理注解,并生成Java辅助类
     *
     * @param set
     * @param roundEnvironment
     * @return
     */
    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
    
    
	Set<? extends Element> annotationElements = 	roundEnvironment.getElementsAnnotatedWith(BindView.class);
	for (Element element : annotationElements){
    
    
    	//获取字段名称
   	 if (element instanceof TypeElement) {
    
    
        		//注解用于类
        		try {
    
    
            	TypeElement typeElement2 = (TypeElement) element;
           	 System.out.println("typeElement2:" + typeElement2);
       	 	} catch (Exception e) {
    
    
            	e.printStackTrace();
        		}
    	} else {
    
     //注解用于字段
    		}
	}
        return false;
    }

    /**
     * 编译期间,init()会自动被注解处理工具调用,并传入ProcessingEnvironment参数,
     * 通过该参数可以获取到很多有用的工具类(Elements,Filer,Messager等)
     */
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
    
    
        super.init(processingEnv);
		elements = processingEnv.getElementUtils();
		messager = processingEnv.getMessager();
		filer = processingEnv.getFiler();
		types = processingEnv.getTypeUtils();

    }

    /**
     * 返回processor可处理的注解
     *
     * @return
     */
    @Override
    public Set<String> getSupportedAnnotationTypes() {
    
    
        Set<String> sets = new HashSet<>();
        sets.add(BindView.class.getCanonicalName());
        return sets;
    }


    /**
     * 用于指定你的java版本,一般返回:SourceVersion.latestSupported()
     */
    @Override
    public SourceVersion getSupportedSourceVersion() {
    
    
        return super.getSupportedSourceVersion();
    }
}

process() メソッドの中心となるのは、プログラムの要素を表す Element 要素です。アノテーション処理中に、コンパイラはすべての Java ソース ファイルをスキャンし、ソース コードの各部分を特定のタイプの要素カスタム処理とみなします
。 Element クラスと他のサブクラスを理解するには、プロセッサ プロセスにも 4 つのヘルパー クラスが必要です。

アノテーションプロセッサヘルパークラス 説明する
要素 Elementを処理するためのツールクラス
種類 TypeMirrorを処理するためのユーティリティクラス
ファイラー ファイルの作成に使用されます (Java ファイルの作成など)
メッセンジャー 出力の場合、print 関数と同様

これら 4 つのヘルパー クラスは、init() 関数の ProcessingEnvironment を通じて取得できます。

アノテーションプロセッサを作成したら、それをアプリモジュールにインポートします

implementation project(":模块名称")

process 関数では、指定されたアノテーションを持つ要素を RoundEnvironment
ソース コードを通じて返すことができます。

public interface RoundEnvironment {
    
     
    // 返回使用给定类型注解的元素。 
    Set<? extends Element> getElementsAnnotatedWith(TypeElement var1); 
    // 返回使用给定类型注解的元素。
    Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> var1);
}

おすすめ

転載: blog.csdn.net/qq_42447739/article/details/125983841