跟王老師學註解(五):讀取註解信息
主講教師:王少華 QQ羣號:483773664
一、註解被讀取
(一)條件
當一個註解類型被定義爲運行時註解後,該註解纔是運行時可以見,當class文件被裝載時被保存在class文件中的註解纔會被Java虛擬機所讀取。
要把@Retention註解的value成員變量的值設爲RetentionPolicy.RUNTIME
(二)辦法
我們已知所有的註解都是繼承的java.lang.Annotation接口,也就是說Annotation是所有接口的父接口。除此之外,在java.lang.reflect包下的新增了AnnotatedElement接口,該接口代表程序中可以接受註解的程序元素,
1、該接口有如下幾個實現類,分別是:
Class:類定義
Constructor:構造方法定義
Field:類的成員變量定義
Method:類的方法定義
Package:類的包定義
2、java.lang.reflect.AnnotatedElement接口是所有程序元素的父接口,程序通過反射獲得某個類的AnnotatedElement對象,調用該對象的3個方法就可以來訪問註解信息。
getAnnotation()方法:用於返回該程序元素上存在的、指定類型的註解,如果該類型的註解不存在,則返回null
getAnnotations():用來返回該程序元素上存在的所有註解。
isAnnotationPresent():用來判斷該程序元素上是否包含指定類型的註解,如果存在返回true,否則返回false.
二、示例
(一)輸出類方法上的所有註解
1、自定義的annotation
12345678 @Target
({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD,
ElementType.PARAMETER, ElementType.CONSTRUCTOR,
ElementType.LOCAL_VARIABLE })
@Retention
(RetentionPolicy.RUNTIME)
public
@interface
MyAnnotation {
String name()
default
"Jack"
;
int
age()
default
20
;
}
2、使用自定義Annotation
12345678 public
class
Person {
private
String name;
private
int
age;
@MyAnnotation
public
void
setInfo(){
}
}
3、測試
12345678910 public
class
AnnotationTest {
public
static
void
main(String[] args)
throws
ClassNotFoundException, NoSuchMethodException, SecurityException {
Class<Person> personClass = (Class<Person>) Class.forName(
"chapter10_04.Person"
);
Method method = personClass.getMethod(
"setInfo"
);
Annotation[] annotations = method.getAnnotations();
for
(Annotation annotation : annotations) {
System.out.println(annotation);
}
}
}
(二)獲取某個註解裏的元數據
123456789101112131415161718 public
class
AnnotationTest {
public
static
void
main(String[] args)
throws
ClassNotFoundException, NoSuchMethodException, SecurityException {
Class<Person> personClass = (Class<Person>) Class.forName(
"chapter10_04.Person"
);
Method method = personClass.getMethod(
"setInfo"
);
Annotation[] annotations = method.getAnnotations();
for
(Annotation annotation : annotations) {
//如果類型是MyAnnotation
if
(annotation
instanceof
MyAnnotation) {
System.out.println(annotation);
//強制類型轉換
MyAnnotation myAnnotation = (MyAnnotation) annotation;
//輸出值
System.out.println(
"myAnnotation.name:"
+myAnnotation.name());
System.out.println(
"myAnnotation.age:"
+myAnnotation.age());
}
}
}
}
三、@Inherited
1 2 3 4 5 6 7 8 | @Target ({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE }) @Retention (RetentionPolicy.RUNTIME) public @interface MyAnnotation { String name() default "Jack" ; int age() default 20 ; } |
1 2 3 4 5 6 7 8 | public class Person { private String name; private int age; @MyAnnotation public void setInfo(){ } } |
1 2 3 4 5 6 7 8 9 10 | public class AnnotationTest { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { Class<Person> personClass = (Class<Person>) Class.forName( "chapter10_04.Person" ); Method method = personClass.getMethod( "setInfo" ); Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class AnnotationTest { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { Class<Person> personClass = (Class<Person>) Class.forName( "chapter10_04.Person" ); Method method = personClass.getMethod( "setInfo" ); Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { //如果類型是MyAnnotation if (annotation instanceof MyAnnotation) { System.out.println(annotation); //強制類型轉換 MyAnnotation myAnnotation = (MyAnnotation) annotation; //輸出值 System.out.println( "myAnnotation.name:" +myAnnotation.name()); System.out.println( "myAnnotation.age:" +myAnnotation.age()); } } } } |
@Inherited : 在您定義註解後並使用於程序代碼上時,預設上父類別中的註解並不會被繼承至子類別中,您可以在定義註解時加上java.lang.annotation.Inherited 限定的Annotation,這讓您定義的Annotation型別被繼承下來。注意註解繼承只針對class 級別註解有效。
(一)改造MyAnnotation
1 2 3 4 5 6 7 8 9 | @Target ({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE }) @Retention (RetentionPolicy.RUNTIME) @Inherited public @interface MyAnnotation { String name() default "Jack" ; int age() default 20 ; } |
(二)繼承類及使用自定義註解
1 2 3 4 | @MyAnnotation public class Fruit { } |
1 2 3 | public class Apple extends Fruit{ } |
(三)獲得父類的annotaion
1 2 3 4 5 6 7 8 9 | public class AnnotationTest2 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException { Class<Apple> appleClass = (Class<Apple>) Class.forName( "chapter10_04.Apple" ); Annotation[] annotations = appleClass.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } } } |