Javaでのアノテーションの原則
I.はじめに
Java5の前に、使用するxml
主要な従来のフレームワークの動作を設定するには、このアプローチは、ほぼすべての必要性を設定するには、疎結合と完全なフレームワークを実現することができますが、拡張プロジェクトで、xml
ファイル自体の内容が非常に複雑になり、メンテナンスコストが大幅に上昇しています。
したがって、関連する情報またはメタデータを、注釈のための同様の機構を提供することができる高タグ結合構成、(メタ)プログラム要素(クラス、メソッド、メンバー変数、等)を使用することが提案されました。プログラム要素(クラス、メソッド、メンバー変数)に加えて、より直感的な説明が、サービスロジック自体のプログラム命令とは無関係に、この関連付けは、特定のツールまたはフレームワークにを提供するように設計されます。
第二に、コメント、何の本質は何ですか?
Javaでは注釈は、指示を果たし、構成機能実行時のコンパイル、解釈および使用中のツールのいくつかのための追加情報のソースコードの一部です。修飾子の宣言は、クラス、メソッド、パラメータ、変数に適用されるとして、あなたは理解するコメントを付けることができます。ノートコード自体が唯一の唯一の性的な脇役を演じることができ、ビジネスロジックには影響を与えません。
アノテーションインタフェースの説明については非常に多くの言葉があります。
それは意味:このインタフェースは、すべての注釈型は共通のインタフェースを継承しているです。この文は理解しにくいかもしれません。私たちの共通して@Override
ノートを例にとる次のように、そのソースコードは次のとおりです。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
私たちの共通の形式を理解するために上記のコード、それは次のサブサブする必要があります:
public interface Override extends Annotation {
}
今、あなたはその性質上、いわゆるノートを理解することができる唯一の継承されたインターフェイスの注釈インタフェースです。
コメントが来るように、及び他の実装クラスは、符号語を解析対応しない場合のインターフェースとして、効果は有用ではないかもしれません。
我々は良いコメントを定義するときに、私たちは、注釈がその原因な役割を果たしますが、基礎となるコードを支援する必要があります。プロキシオブジェクト動的に生成されたJavaランタイムを返す反射を介して取得された基礎となるコード注釈後ながら、ランタイムプロキシクラスに動的に生成されたコードの実装クラスである特別なインターフェース、などの注釈$Proxy
。プロキシはプロキシオブジェクトのオブジェクトによって、カスタム注釈(インタフェース)メソッドの呼び出しを、それが呼び出すことになります方法を。この方法に対応する値のインデックス。Javaの定数プールのソース。AnnotationInvocationHandler
invoke
memberValues
Map
memberValues
第三に、メタアノテーション
注釈は、基本的に彼らの特定の機能を実現するためだけのインタフェースは、基礎となるコードを支援するために必要されているので、我々は、我々はこのコメントが何を作るために基礎となるコードを聞かせする必要があります知っていますか?Javaは、問題を解決するために私たちを助けるためのメタアノテーションを提供します。
メタアノテーションは、カスタム注釈のためのアノテーションの修正ノートのために提供されます。
注釈は4元のノートの合計を提供し、以下のとおりです。
@Target:ターゲットの役割を指摘し、
@Retention:注釈文の期間;
@継承:継承できるようにするかどうかを示します。
@Documented:ノートはのJavaDocに含まれるかどうか。
@ターゲット
@targetこの注釈を指定するために使用される役割の変更、最終的なノートに指定されたターゲットは、最終的な方法を変更するために使用、またはクラスまたは属性の変更を変更していますか?
@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();
}
上記の例@Overrideソースコードでは、@Target(ElementType.METHOD)
それが唯一の注釈のために使用することができるこの方法のコードを変更することによって示されるように、クラスが使用されるか、またはプロパティを変更することはできません。列挙型であるのElementType、から選択するには、次の値が設定されています
クラス、インターフェイス、および列挙で修正役割に関するコメントを許可:ElementType.TYPEを
ElementType.FIELD:属性フィールドに作用させ
ElementType.METHOD:の方法に作用させ
ElementType.PARAMETER:メソッドのパラメータに作用させ
ElementType.CONSTRUCTOR:コンストラクタに作用させ
ElementType.LOCAL_VARIABLE:ローカルローカル変数に作用させ
ElementType.ANNOTATION_TYPE:ノートに作用させ
ElementType.PACKAGE:クラッドに作用させ
@Retation
@Retentionアノテーションは次のように現在のライフサイクルは、ソースコードであることを示しています。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
上記と一致して、コメントはまた、プロパティの値を有し、これはまた、次の値を含むRetentionPolicy列挙型を提供します。
RetentionPolicy.SOURCE:コンパイル時に破棄。コンパイラの最後にこれらのアノテーションは、もはや彼らはバイトを書いていない、何の意味もありません。@Override、@SuppressWarningsは、このようなコメントに属します。
RetentionPolicy.CLASS:廃棄されたクラスのロード。便利なバイトコードファイル。メモは、この方法をデフォルト
RetentionPolicy.RUNTIMEは:ランもノートを保つために廃棄されることはありませんので、あなたは、注釈情報を読み取るためにリフレクションを使用することができます。一般的にこのように使用される当社のカスタム注釈します。
@Documented&@Inherited
@Documentedコメントはパッケージ化するときに破棄されます逆に、我々はJavadocドキュメントを実行すると、パッケージがドキュメントのドキュメントに保存され、コメントを修正しました。
@Inherited注釈ノート修正継承され、また、我々は、クラスを変更することを指摘し、そのクラスのサブクラスは、自動的に親クラスのノートを継承します。
第四に、一般的な注釈
@オーバーライド
java.lang.Overrideは標識方法として使用されるマーカー注釈型です。これは、メソッドが親クラスのオーバーロードマークされている示し、アサーションが役割を果たしました。私たちがカバーしていない親クラスのメソッドの方法でこの注釈を使用する場合は、Javaコンパイラの警告は、コンパイルエラーになります。
@Deprecated
非推奨は、マーカーの注釈のタイプです。修正@Deprecated型または型のメンバを使用する場合、コンパイラは、このプログラム要素がマークされているの使用を奨励しません。したがって、この変形例の使用は、特定の「連続性」を有する:相続のタイプは@Deprecatedとして宣言された後、被覆されていないが、我々は、継承を介して、または、この廃止型またはメンバー、またはメンバーを使用して、コード・モードで覆われている場合、しかし、コンパイラは、まだ警察に報告しました。
@SuppressWarnings
マーク型注釈ではないSuppressWarning。それは、String []型のメンバーの種類を持って禁止警告名のメンバーです。javacコンパイラが懸念しているために、オプションが@SuppressWarings名に-Xlint効果的な警告も有効であるが、コンパイラは無視され、警告の名前を認識しません。@SuppressWarnings( "未チェック")
V.カスタム注釈
カスタム注釈カテゴリを記述するためのいくつかのルール:
- 注釈タイプは、すべての注釈は自動的にこのインタフェースjava.lang.Annotationを継承する、@interfaceとして定義され、別のクラスまたはインタフェースを継承して行くことができません。
- パラメータは、これらの2つの修飾にデフォルト(デフォルト)アクセスの公開やメンバーを使用することができます
- メンバーは、唯一のタイプのバイト、ショート、CHAR、int型、長い、フロート、ダブル、ブール8つの基本データ型と文字列、列挙型、クラス、注釈および他のデータ型の基本的なパラメータと同様に、この配列のいくつかのタイプを使用することができます。
- クラスメソッドやフィールドでは、アノテーション情報がアノテーションを介して取得しなければならないが、反射技術をオブジェクトに加えて、あなたは、オブジェクトの注釈を取得するための他の方法を持っていないので、
- メモもメンバーを定義することができ,,しかし、このような無駄にコメントしませんでした
PS:自定义注解需要使用到元注解
シックス・カスタム注釈例
FruitName.java
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 水果名称注解
*/
@Target(ElementType.FIELD)
@Retention(RUNTIME)
@Documented
public @interface FruitName {
String value() default "";
}
FruitColor.java
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 水果颜色注解
*/
@Target(FIELD)
@Retention(RUNTIME)
@Documented
public @interface FruitColor {
/**
* 颜色枚举
*/
public enum Color{ BLUE,RED,GREEN};
/**
* 颜色属性
*/
Color fruitColor() default Color.GREEN;
}
FruitProvider.java
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 水果供应者注解
*/
@Target(FIELD)
@Retention(RUNTIME)
@Documented
public @interface FruitProvider {
/**
* 供应商编号
*/
public int id() default -1;
/**
* 供应商名称
*/
public String name() default "";
/**
* 供应商地址
*/
public String address() default "";
}
FruitInfoUtil.java
import java.lang.reflect.Field;
/**
* 注解处理器
*/
public class FruitInfoUtil {
public static void getFruitInfo(Class<?> clazz){
String strFruitName=" 水果名称:";
String strFruitColor=" 水果颜色:";
String strFruitProvicer="供应商信息:";
Field[] fields = clazz.getDeclaredFields();
for(Field field :fields){
if(field.isAnnotationPresent(FruitName.class)){
FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
strFruitName=strFruitName+fruitName.value();
System.out.println(strFruitName);
}
else if(field.isAnnotationPresent(FruitColor.class)){
FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
System.out.println(strFruitColor);
}
else if(field.isAnnotationPresent(FruitProvider.class)){
FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
System.out.println(strFruitProvicer);
}
}
}
}
Apple.java
import test.FruitColor.Color;
/**
* 注解使用
*/
public class Apple {
@FruitName("Apple")
private String appleName;
@FruitColor(fruitColor=Color.RED)
private String appleColor;
@FruitProvider(id=1,name="陕西红富士集团",address="陕西省西安市延安路89号红富士大厦")
private String appleProvider;
public void setAppleColor(String appleColor) {
this.appleColor = appleColor;
}
public String getAppleColor() {
return appleColor;
}
public void setAppleName(String appleName) {
this.appleName = appleName;
}
public String getAppleName() {
return appleName;
}
public void setAppleProvider(String appleProvider) {
this.appleProvider = appleProvider;
}
public String getAppleProvider() {
return appleProvider;
}
public void displayName(){
System.out.println("水果的名字是:苹果");
}
}
FruitRun.java
/**
* 输出结果
*/
public class FruitRun {
public static void main(String[] args) {
FruitInfoUtil.getFruitInfo(Apple.class);
}
}
業績は以下のとおりです。
果物の名前:アップルの
果実の色:RED
取引先コード:サプライヤー名1:陝西富士グループのサプライヤー住所:西安、陝西省、延安路、ビル89のフジ
VII参照
- https://www.cnblogs.com/acm-bingzi/p/javaAnnotation.html
侵害した場合、削除された連絡してください!