简而言之:我如何检测给定用户类/对象是否存在(并且在正确的位置)java注释。
“问题”的详情
假设我有两个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对象包含Cells。
我还有两个注释,例如:
public @interface Line {
// some stuff here
}
public @interface Cell {
// some stuff here
}
我还有一堆用户类(本例中有两个用户类)包含我指定的@Line和@Cell注释,如:
@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
注释的用户类,以及其成员的至少一个@Cell
注释才是可以传递到Line对象的构造函数的有效对象。
所有其他传递的对象都无效。传递有效用户对象的那一刻,该对象中标记为@Cell
的所有可用成员都将转换为Cell对象并添加到单元格列表中。
我的问题:
@Cell
标记成员的数据类型?这是必需的,因为Cell类不接受所有数据类型。@Cell
(没有名称)和@Cell(name="aName")
,并且当仅指定@Cell
时,将使用成员的名称。我不知道这些信息在运行时是否仍然可以使用反射。@Cell // oh oh, that's no good :(
public class WrongClass {
// some members
}
感谢您的帮助!
答案 0 :(得分:43)
首先,您需要在注释上设置保留政策,以便您可以使用反射
来阅读它们 @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public static @interface Line {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public static @interface Cell {
}
其次,您需要测试该类是否具有isAnnotationPresent(annotationClass)
的行注释。可以从java.lang.Class
和java.lang.reflect.Field。
注意:您需要检索class.getDeclaredField(fieldName)
专用的字段。
3.
我认为您不能使注释具有基于propertyName的默认值,但您可以通过提供默认值String name() default DEFAULT
使名称成为可选,并在迭代时检查该值字段,并使用name()
或propertyName
答案 1 :(得分:20)
问题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
保留作用域的注释,