注解的提取
我通过用标签来比作注解,前面的内容是讲怎么写注解,然后贴到哪个地方去,而现在我们要做的工作就是检阅这些标签内容。 形象的比喻就是你把这些注解标签在合适的时候撕下来,然后检阅上面的内容信息。
要想正确检阅注解,离不开一个手段,那就是反射。
注解与反射
注解通过反射获取。首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解
public
boolean
isAnnotationPresent
(Class<? extends Annotation> annotationClass) {}
然后通过 getAnnotation() 方法来获取 Annotation 对象。
public
<A extends Annotation> A
getAnnotation
(Class<A> annotationClass) {}
或者是 getAnnotations() 方法。
public
Annotation[]
getAnnotations
() {}
前一种方法返回指定类型的注解,后一种方法返回注解到这个元素上的所有注解。
@TestAnnotation
()
public
class
Test {
public
static
void
main
(String[] args) {
boolean
hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);
if
( hasAnnotation ) { TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class); System.out.println(
"id:"
+testAnnotation.id()); System.out.println(
"msg:"
+testAnnotation.msg()); } }}
上面的例子中,只是检阅出了注解在类上的注解,其实属性、方法上的注解照样是可以的。同样还是要假手于反射。
@TestAnnotation
(msg=
"hello"
)
public
class
Test {
@Check
(value=
"hi"
)
int
a;
@Perform
public
void
testMethod
(){}
@SuppressWarnings
(
"deprecation"
)
public
void
test1
(){ Hero hero =
new
Hero(); hero.say(); hero.speak(); }
public
static
void
main
(String[] args) {
boolean
hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);
if
( hasAnnotation ) { TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class);
//获取类的注解
System.out.println(
"id:"
+testAnnotation.id()); System.out.println(
"msg:"
+testAnnotation.msg()); }
try
{ Field a = Test.class.getDeclaredField(
"a"
); a.setAccessible(
true
);
//获取一个成员变量上的注解
Check check = a.getAnnotation(Check.class);
if
( check !=
null
) { System.out.println(
"check value:"
+check.value()); } Method testMethod = Test.class.getDeclaredMethod(
"testMethod"
);
if
( testMethod !=
null
) {
// 获取方法中的注解
Annotation[] ans = testMethod.getAnnotations();
for
(
int
i =
0
;i < ans.length;i++) { System.out.println(
"method testMethod annotation:"
+ans[i].annotationType().getSimpleName()); } } }
catch
(NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace(); System.out.println(e.getMessage()); }
catch
(SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace(); System.out.println(e.getMessage()); }
catch
(NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace(); System.out.println(e.getMessage()); } }}
注解的使用场景
当开发者使用了Annotation 修饰了类、方法、Field 等成员之后,这些 Annotation 不会自己生效,必须由开发者提供相应的代码来提取并处理 Annotation 信息。这些处理提取和处理 Annotation 的代码统称为 APT(Annotation Processing Tool)。
总结
- 如果注解难于理解,你就把它类同于标签,标签为了解释事物,注解为了解释代码。
- 注解的基本语法,创建如同接口,但是多了个 @ 符号。
- 注解的元注解。
- 注解的属性。
- 注解主要给编译器及工具类型的软件用的。
- 注解的提取需要借助于 Java 的反射技术,反射比较慢,所以注解使用时也需要谨慎计较时间成本。