簡単に言えば、特定のユーザークラス/オブジェクトに対してJavaアノテーションが(適切な場所に)存在するかどうかを検出するにはどうすればよいですか。
「問題」の詳細
2つのJavaクラスがあります:
public class Line {
private List<Cell> cells;
public Line(Object... annotatedObjects) {
// check if annotations @Line and @Cell are present in annotatedObjects.
}
// getter/setter for cells.
}
public class Cell {
// some members
// some methods
}
Lineオブジェクトはセルを保持します。
次のような2つの注釈もあります。
public @interface Line {
// some stuff here
}
public @interface Cell {
// some stuff here
}
また、次のように、指定した@Lineアノテーションと@Cellアノテーションを含む多数のユーザークラス(この例では2つ)があります。
@Line(name="pqr", schema="three")
public class AUserClass {
@Cell
private String aString;
}
@Line(name="xyz", schema="four")
public class AnotherUserClass {
@Cell(name="birthday")
private Date aDate;
}
問題:新しいLineオブジェクトをインスタンス化するときに、ユーザークラス/オブジェクトをLineコンストラクターに渡すことができるようにします。 Lineコンストラクターは、渡されたユーザークラス/オブジェクトが処理可能な有効なクラスであるかどうかを確認します。クラスの@Line
注釈と、そのメンバーの少なくとも1つの@Cell
注釈を持つユーザークラスのみが、Lineオブジェクトのコンストラクターに渡すことができる有効なオブジェクトです。他のすべての渡されたオブジェクトは無効です。有効なユーザーオブジェクトが渡されると、そのオブジェクトで@Cell
としてタグ付けされている使用可能なすべてのメンバーがCellオブジェクトに変換され、セルリストに追加されます。
私の質問:
@Cell
タグ付きメンバーのデータ型を検出することは可能ですか? Cellクラスはすべてのデータ型を受け入れないため、これが必要です。@Cell
を書きたい(名前なし)および@Cell(name="aName")
で、@Cell
のみが指定されている場合は、代わりにメンバーの名前が使用されます。@Cell // oh oh, that's no good :(
public class WrongClass {
// some members
}
ご協力ありがとうございました!
まず、リフレクションでそれらを読むことができるように、アノテーションに保持ポリシーを設定する必要があります
_ @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public static @interface Line {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public static @interface Cell {
}
_
次に、クラスにisAnnotationPresent(annotationClass)
のLine注釈があるかどうかをテストする必要があります。このメソッドには、_Java.lang.Class
_およびJava.lang.reflect.Fieldからアクセスできます。
[〜#〜] note [〜#〜]:class.getDeclaredField(fieldName)
でプライベートなフィールドを取得する必要があること。
_3.
_ propertyNameに基づいて注釈にデフォルト値を持たせることはできないと思いますが、デフォルトのString name() default DEFAULT
を指定して名前をオプションにし、フィールドを反復処理するときにその値を確認できますname()
またはpropertyName
に保存されている値を使用します
Q.1:実行時にこのオブジェクト/クラスの注釈を検出することは可能ですか?これは渡されたオブジェクトのみです(クラスパスで注釈をスキャンしたくない!)?
はい isAnnotationPresent を使用して非常に可能です
@Deprecated
public class AnnotationDetection {
public static void main(String[] args) {
AnnotationDetection annotationDetection = new AnnotationDetection();
System.out.println(annotationDetection.getClass().isAnnotationPresent(Deprecated.class));
}
}
注Runtime
で保持するスコープの注釈のみが利用可能です。