JAVAの深さの研究ノート-annotation(学習プロセス)

JAVAの研究ノート-annotation

この記事の目的:プロジェクトの開発プロセス遭遇したカスタム注釈は、あなたが原則を把握したいのですが、この問題を調査するために、自分の知識ベースをサポートするのに十分ではない、私たちが最初に記録の質問は、その後、基本を加え、その問題を解決します。この学習過程を記録します。

プロジェクトノートに発生しました:

//使用注解的地方
@ServiceScan({"com.sinosoft.lis.pubfun"})
public class CodeQuerySQL {}

//注解类 ServiceScan
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ServiceScan {
    String[] value() default {};
}

//这个com.sinosoft.lis.pubfun包下的类
@CodeQuery
public interface CodeQuery_Framework {}

//注解类CodeQuery
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface CodeQuery {
}

問題の説明:開発、私たちはライン上の次のcom.sinosoft.lis.pubfunパッケージに使用される新しいcodequeryframework_nb独自のクラスを作成し、メソッドをカスタマイズする必要があり、それが自動的にスキャンして、自動的にロードされますこのクラスで定義されたインタフェースメソッドは、私たちのお問い合わせプルダウン機能を実現しています。使用可能な適切な場所を含め、正しいノートを使用しますが、なぜ以前codequeryframeworkと競合していないのですか?具体的に達成するためにどのように、私たちのグループのメンバーは、徹底的に理解していませんでした。私は発掘を掘るための知識の深さに注釈を付けることにしました。

私たちの質問:

  1. この機能は実現する方法です。
  2. なぜ、以前に作成し、クラスの競合ではありません。
  3. 実際には、どのように実現しています。

学習の目標:

  1. 説明できる:このクラスは、アノテーションを通じて達成する方法である理由
  2. ノートを使用する方法、注釈が何であるかを理解し、注釈を実装原理

注意基本は加えました:

プロセスを学びます:

  1. まず、おそらくノートのいくつかの知識を持っているデータに最初に行きます。https://www.runoob.com/w3cnote/java-annotation.html
  2. 出会うブロガーのいくつかは、彼らが大きなポイントに記載されているかを確認するためにブログ、基本的に同じであるので、あなたは最初、彼らが必要なものを理解するために移動することができます学び、理解することです
  3. プロセスに関する質問については、リークがいっぱい。自分の疑問のために

他の人の知識を挙げる:java5、メタアノテーション、注釈のプロパティの実現にカスタムコメント、ノート反射での注釈の使用の役割を

自然の注釈

//「java.lang.annotation.Annotation」接口中有这么一句话,用来描述『注解』。
The common interface extended by all annotation types
所有的注解类型都继承自这个普通的接口(Annotation)

レッツはちょうどJDKの方法を定義を見以内に注釈を開いています

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

これは、実際に、それは本質的に、定義@Overrideノートです:

 public interface Override extends Annotation{
     
 }

はい、性質が継承された注釈インターフェイス注釈インタフェースです。この点で、あなたは結果を得るだろう、アノテーションクラスのいずれかをコンパイルするために行くことができます。

なぜ使用注釈?

ここでは、2人のブロガーの決意を見つけ、私は場所を理解することは非常に簡単に感じます。まず全体的に理解します。

我々は付箋紙を使用した場合、通常では、私たちは必要な場所に取り付けた一枚の紙、上のいくつかの文章を書き、知りません。ほとんどの人が、その後死亡し、私たちのプログラムAPE(少ないお金を呼び出している状況もあり、速い)、これは私たちに貼られたラベルです。これらの2つの場合のようにそれは基本的にコメントです。あなたは、コードにコメントするには、これらの2例を考えることができます。例えば、我々はメソッドを定義し、さらに動作を実現するには、この方法では、我々は@ADDラベルを定義することができます。この方法は追加を達成することであることを示しています。我々は、このプログラマ@ADDは、簡単にこの方法をやっている理解することができます参照してください。簡単に言えば。特定の新鮮な個人のコードは、ラベル用に掲示することをメモ。簡素化された用語は、ラベルとして注釈付き。そのため、あなたはこのような便利なラベルとして彼を置くことができる前に、あなたはまだ正式にノートを研究していない場合は、注釈のほとんどを理解するのに役立ちます。

以前は、「XML」は、事実上すべての構成のためのフレームワークを完了するための主要な疎結合フレームワークの方法によって支持されていますが、より多くの大規模なプロジェクトで、「XML」の内容は、ますます複雑になってきている、メンテナンスコスト高いです。だから一部の人は「ノート」、前方に高い結合型の構成のマークアップを置きます この方法は、クラスが注釈を付けることができ、フィールド属性がほとんどとにかくあなたが設定する必要がどこにも、注釈を付けることができる注釈を付けることができ、注釈を付けることができます。長年にわたって議論、「ノート」と二つの異なるコンフィギュレーションモードで、「XML」、について、それぞれ独自の長所と短所があり、注釈は利便性、メンテナンス変更の容易さが、高結合、およびXMLに関してを提供することができますコメントが逆転しています。我々は低結合効率の追求を放棄する必要があり、効率の追求は、出会いのカップリングにバインドされています。この記事は、両方に優れている、もはや区別するために意図されていますが、最も簡単な言語の基本的なコンテンツに関連するノートを紹介します。

元のメモ

元は役割ノート:

「メタ注釈」は、通常の定義注釈では、注釈付きのノートを変更するために使用されます

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

これは、2つのノートは、我々は一般的にアノテーション情報ライフサイクルと目標の役割を指定するために使用される「メタアノテーション」、「メタアノテーション」と呼んで保持@​​、ターゲット@それらを見ることができ、@Overrideアノテーションの私達の定義です。

メタアノテーションものですので、
//目前jdk官方提供的元注解有4个
@Target:定义注解的作用目标
@Retention:定义注解的生命周期
@Documented:定义注解是否应当被包含在 JavaDoc 文档中
@Inherited:定义是否允许子类继承该注解
詳細元のメモ
  1. @Target -ターゲットが最後にあなたのコメントに指定されている修正注釈付き最終的役割を示すために使用される方法を変更するために使用されていますか?変更されたクラス?またはフィールドのプロパティを変更するために使用。次のようにターゲットが定義されています。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

私たちは、途中、この値によって値を渡すことができます。

 @Target(value = {ElementType.FIELD})

この注釈付き修正@Targetコメントは、メソッドやクラスを変更するために使用することはできません、メンバーフィールドに作用します。これは、のElementTypeが列挙型で、次の値のいくつかがあります。

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,  //允许被修饰的注解作用在类、接口和枚举上

    /** Field declaration (includes enum constants) */
    FIELD, //允许作用在属性字段上

    /** Method declaration */
    METHOD,  //允许作用在方法上

    /** Formal parameter declaration */
    PARAMETER, //允许作用在方法参数上

    /** Constructor declaration */
    CONSTRUCTOR, //允许作用在构造器上

    /** Local variable declaration */
    LOCAL_VARIABLE,  //允许作用在本地局部变量上

    /** Annotation type declaration */
    ANNOTATION_TYPE,  //允许作用在注解上

    /** Package declaration */
    PACKAGE,   //允许作用在包上

    /**
     * Type parameter declaration
     * 表示该注解能写在类型变量的声明语句中(如:泛型声明)。
     * @since 1.8 
     */
    TYPE_PARAMETER,  

    /**
     * Use of a type
     * 表示该注解能写在使用类型的任何语句中。
     * @since 1.8
     */
    TYPE_USE
}

注意:上述中文翻译为自己翻译的,如果有错误,请自行查阅官方文档
最后从jdk1.8添加的两个枚举类型的作用,是通过搜索网络资料查询得来
类型注解: JDK1.8之后,关于元注解@Target的参数类型ElementType枚举值多了两个:
TYPE_PARAMETER和TYPE_USE。

在Java8之前,注解只能是在声明的地方所使用,Java8开始,注解可以应用在任何地方。
ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)。
ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。
  1. @Retention -この注釈は、コードだけで、保存された、またはクラス・ファイルに組み込まれ、または実行時にリフレクションを介してアクセスすることができる方法を特定します。これは次のように、実質的に定義されます。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

同様に、それはまた、value属性があります。

@Retention(value = RetentionPolicy.RUNTIME

RetentionPolicyは、ここでは、以下の望ましい列挙値を持って、まだ列挙型です。

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,  //当前注解编译期可见,不会写入 class 文件

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,  //类加载阶段丢弃,会写入 class 文件

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME  //永久保存,可以反射获取
}

注釈付きに変更ライフサイクルは、一つだけはコンパイル時に表示されていることを@Retention注釈指定は、それは、コンパイラにクラスにコンパイルされたファイルをコンパイルした後、クラスやメソッド、および偶数フィールドのいずれかを破棄されますクラスがロードされたときに、すべてのプロパティシートで、JAVA仮想マシンはまた、注釈情報を格納するためのいくつかのアノテーション属性テーブルを定義していますが、これは可視域の方法をもたらしたことができない、最後の1は、破棄されます視認性の永続的。

ライフサイクルを確認するには?

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface TestAnnotation {
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation2 {
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface TestAnnotation3 {
}
@TestAnnotation
@TestAnnotation2
@TestAnnotation3
public class TestJava {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> testJava = Class.forName("com.sinosoft.lis.pubfun.TestJava");
        Annotation[] annotations = testJava.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation.annotationType());
        }

    }

あなたは私が何を意味するか知っています。

  1. @Inherited - (コメントへのデフォルトおよび任意のサブクラスを継承しませんでした)継承された注釈クラスでこのコメントをマークします。
  2. @Documented - ユーザーマニュアルに記載されているこれらのノートをマーク。

比較的単純な、小さな私たちの毎日の使用の注釈の残りの2種類があり、詳細な説明はなかった、とだけそれぞれの役割を知っている必要があります。
コメントを修正@Documentedノート、我々はJavadocドキュメントパッケージを実行するときドキュメントは、ドキュメントに保存され、パッケージ化する際逆もまた同様破棄されます。
@継承された注釈コメントが継承に変更され、また、我々は、クラスを変更することを注記し、そのクラスのサブクラスは、自動的に親クラスを継承しますコメント。

JAVAは、内蔵の3つの音を提供します

#### 除了上述四种元注解外,JDK 还为我们预定义了另外三种注解,它们是:
1. @Override
2. @Deprecated
3. @SuppressWarnings
JAVAは、内蔵の3つの音を提供 - 詳細

1. @Overrideあなたは次のように定義されたラベルの書き換え方法、非常に精通している必要がありコメント:

/**
 * Indicates that a method declaration is intended to override a
 * method declaration in a supertype. If a method is annotated with
 * this annotation type compilers are required to generate an error
 * message unless at least one of the following conditions hold:
 *
 * <ul><li>
 * The method does override or implement a method declared in a
 * supertype.
 * </li><li>
 * The method has a signature that is override-equivalent to that of
 * any public method declared in {@linkplain Object}.
 * </li></ul>
 *
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 9.6.1.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

これは、任意のプロパティを持っていないので、その他の情報を格納しないでください。それだけで、それがコンパイルの終了後に破棄され、上記の方法に基づいて行動することができます。あなたが見るので、それだけでコンパイラを示し、方法の検出時に、バイトコードにコンパイルされたJavaファイルの過程で、コンパイラは、コメントの変更である「タグ型ノート」典型的なものですない場合は、馬が親クラスが機能同じメソッドシグネチャを持っているかどうかに行くだろう、コンパイルができませんでした。

2. @Deprecated:主に次のように実質的に定義され、古くなっ要素をマークするために使用

/**
 * A program element annotated &#64;Deprecated is one that programmers
 * are discouraged from using, typically because it is dangerous,
 * or because a better alternative exists.  Compilers warn when a
 * deprecated program element is used or overridden in non-deprecated code.
 *
 * @author  Neal Gafter
 * @since 1.5
 * @jls 9.6.3.6 @Deprecated
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

それでも「マーカー注釈型」永久的である、あなたはすべてのタイプを変更することができるなど、現在のクラスやメソッド、またはフィールドをマークすることですが、もはや使用することは推奨され、JDKの次のバージョンが削除されますないかもしれません。もちろん、コンパイラはもはや現在のメソッドやクラスを使用して推奨されていないあなたが、自分のJDKを教えてください強制しません、私はあなたが交換を使用することをお勧め。

3. @SuppressWarnings:主に次のように実質的に定義されている警告を抑制するために使用するJava。

/**
 * Indicates that the named compiler warnings should be suppressed in the
 * annotated element (and in all program elements contained in the annotated
 * element).  Note that the set of warnings suppressed in a given element is
 * a superset of the warnings suppressed in all containing elements.  For
 * example, if you annotate a class to suppress one warning and annotate a
 * method to suppress another, both warnings will be suppressed in the method.
 *
 * <p>As a matter of style, programmers should always use this annotation
 * on the most deeply nested element where it is effective.  If you want to
 * suppress a warning in a particular method, you should annotate that
 * method rather than its class.
 *
 * @author Josh Bloch
 * @since 1.5
 * @jls 4.8 Raw Types
 * @jls 4.12.2 Variables of Reference Type
 * @jls 5.1.9 Unchecked Conversion
 * @jls 5.5.2 Checked Casts and Unchecked Casts
 * @jls 9.6.3.5 @SuppressWarnings
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

それはあなたが値を渡すためのイニシアチブを取る必要があるとvalue属性を持ち、この値は、それが何を意味して表し、この値は、警告の種類を表し抑制する必要があります。例えば:

public static void main(String[] args) {
    Date date = new Date(2019, 12, 27);
}

プログラムの起動時にコードの一部ので、コンパイラは警告を報告します。

警告:(8、21)のjava:java.util.Date日付(int型、int型、int型)廃止

我々は、プログラムが起動したくない場合や、あなたのコード時代遅れの方法コンパイラのチェックは、あなたが@SuppressWarningsコメントを使用し、それを抑制チェックコンパイラに渡された値の属性パラメータ値を与えることができます。

@SuppressWarning(value = "deprecated")
public static void main(String[] args) {
    Date date = new Date(2019, 12, 27);
}

あなたはコンパイラが古いメソッド呼び出しをチェックしないことがわかりますので、次の主な方法は、このような警告のコンパイラのチェックを抑制します。

もちろん、JAVAは、アラートの多くの種類があり、彼らは、検査の種類に警告、このタイプのを抑制するためにvalue属性の値を設定することで、文字列に対応します。

カスタム注釈:

カスタム注釈の構文は比較的簡単です、あなたは次のような構文によってコメントをカスタマイズすることができます。

public @interface InnotationName{
    
}

メタ注釈の選択も変更されたとき、あなたの注釈のライフサイクル、スコープやその他の情報を指定して、より特異的であることができるので、もちろん、カスタムアノテーションは、使用することができます。

アノテーションを使用し&&注釈のプロパティ

Annotationプロパティもメンバ変数として知られています。注変数のメンバーだけ、方法はありません。注釈付きのメンバ変数は、メソッド名は、メンバ変数の戻り値のタイプを定義するメンバ変数の名前を定義することを宣言し、「不可視パラメータ法」フォームに注釈を定義しました。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    int id();
    String msg();
}

上記のコードは、この注釈は、2つのプロパティidとMSGを有するTestAnnotationを定義します。使用に際して、我々は彼らに割り当てられるべきです。

割り当てアプローチは注釈括弧内の複数の属性と、値=「」形にされる前に、離間。

その注釈型のプロパティの定義で8プリミティブデータ型クラス、インタフェース、注釈とそのアレイを適用しなければならないことに留意されたいです。

注釈のプロパティがデフォルト値を持つことができ、デフォルトは、デフォルトのキー値を指定する必要があります。例えば:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    public int id() default -1;
    public String msg() default "Hi";
}

TestAnnotation id属性のデフォルト値-1、msg属性のデフォルト値こんにちは。それはそう適用することができます。

@TestAnnotation()
public class Test {}

そのため、デフォルト値なので、@TestAnnotationブラケットの後ろに再び割り当てなしで、この工程を省略することができます。

最後に、1ケースは、プロパティは、任意のコメントを持っていないことに注意します。そのようなものとして

public @interface Perform {}

だから、ときに、このコメントの適用は、括弧を省略することができます。


これまでのところ:私は知っている彼らは、それを達成する方法であると特異的にどのように注釈を定義していますか?

  1. 例えば@Overrideはどのようにチェックするのですか?それはそれは非常に簡単に定義されたかどうかを確認するために、ソースコードを開いた後、
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
  1. 別の例として、私は、それは自動的に私が文書ドキュメントの生成時に書いたものに係る文書を生成します@Documentedコメント上記のクラスを追加しましたか?彼がどのように達成することですか?アノテーションクラスを走査することにより、それを行うには?
  2. 別の例として、以前に使用@Beanコメントは、私たちは、スキャンがコンテナそれにロードされたときにロードされるクラスでのJavaの定義の後、春に時間枠を使うのか?具体的にどのようにそれを達成するには?
  3. 私は、この問題の非常に明確な理解を書き込むために必要と感じました。独自の推定値は約言及している他の人々を反映することができると

まあ。これら二つの質問では、我々はダウン学習し続けます。


Notesと反射

注釈の詳細に関する私たちの上に、それはまた、簡単にエンドそうでノートの本質とは何か、今、私たちは、仮想マシンレベルで見ている「コメントの本質は、注釈インタフェースコネクタが継承される」、言及することができます。

注釈の使用例

以下のような地元の注釈のあまり使用、:
JUnitのテストフレームワークは、これは次のように典型的な用途があります:

public class ExampleUnitTest {
     @Test
     public void addition_isCorrect() throws Exception {
         assertEquals(4, 2 + 2);
     }
 }

例のSSMフレームワーク、springboot、springcloudので、ノートの多くを使用するためにあります。

概要

注釈の基本的な理解を持っていると考え。それの自己概要について話しています。

  1. ノートは理解することが困難な場合、あなたは物事を説明するために、ラベルに似たラベルを、それを入れて、コードを説明する注釈付き。
  2. 注釈の基本的な構文は、インターフェイスのように作成しますが、@記号より。
  3. メタ注釈の注釈。
  4. プロパティの注釈。
  5. 使用するソフトウェアのコンパイラおよびツールタイプの主なコメント。
  6. 抽出注釈が必要ので、コストを気にするためにアノテーションの時間を使用する場合は注意する必要が遅く反映したJava技術の反射の助けを借り、(反射,!重要な研究対象にします)。

私の前の質問:

  1. I INFER、私の前の質問には、上記の注意事項では見られません。
  2. 私はノートを通じて、行って反映されていた機能の問題。注釈は、単に機能の完全な注釈を果たしました。
  3. あなたはそれを勉強する必要が次です:リフレクション。

反射によって全て@CodeQueryクラスまたはインタフェースが変更されてスキャンし、一元管理への豆容器の形態で被験体に注入され、修飾@CodeQueryクラスまたはインタフェースによれば、修飾@CodeQueryを決定することができますそして、あなたはすべての@SQLの名前を取得するメソッドクラスのリフレクションを使用することができ、すべてのファイルを介し素敵なクラス、クラス何である方法を変更し、あなたは、SQL文を実行するには、名前のメソッドにより、実行時に対応するインターフェイスを呼び出すことができますインクルード


参考文献:

  • https://www.cnblogs.com/yangming1996/p/9295168.html
  • https://www.cnblogs.com/love-menglong/p/11165469.html
  • https://www.runoob.com/w3cnote/java-annotation.html
  • https://blog.csdn.net/tainxiawuti/article/details/99644352
  • https://www.cnblogs.com/skywang12345/「ビッグブラザー」

拡張求人

  1. クラスのソースコードレビューと、そのような注釈アプローチを表示する機能として内蔵された方法、の内部を理解するクラスを反映。
    Class<TestJava> testJavaClass = TestJava.class;
    testJavaClass.getAnnotations();
  1. 基本となる知識の重要性を認識し、私は、基礎となるのJavaのパワーを感じました。
  2. 理論的な知識、実用的なアプリケーション、分析アプリケーションシナリオの反射。

おすすめ

転載: www.cnblogs.com/wobushitiegan/p/12460575.html