跟王老师学注解(五):利用反射读取注解信息

跟王老师学注解(五):读取注解信息

主讲教师:王少华   QQ群号:483773664

1、注解被读取

(一)条件

当一个注解类型被定义为运行时注解后,该注解才是运行时能够见,当class文件被装载时被保存在class文件中的注解才会被Java虚拟机所读取。
java

要把@Retention注解的value成员变量的值设为RetentionPolicy.RUNTIMEapp

(二)办法

咱们已知全部的注解都是继承的java.lang.Annotation接口,也就是说Annotation是全部接口的父接口。除此以外,在java.lang.reflect包下的新增了AnnotatedElement接口,该接口表明程序中能够接受注解的程序元素,ide


一、该接口有以下几个实现类,分别是:

Class:类定义测试

Constructor:构造方法定义ui

Field:类的成员变量定义spa

Method:类的方法定义code

Package:类的包定义对象


二、java.lang.reflect.AnnotatedElement接口是全部程序元素的父接口,程序经过反射得到某个类的AnnotatedElement对象,调用该对象的3个方法就能够来访问注解信息。

getAnnotation()方法:用于返回该程序元素上存在的、指定类型的注解,若是该类型的注解不存在,则返回nullblog

getAnnotations():用来返回该程序元素上存在的全部注解。继承

isAnnotationPresent():用来判断该程序元素上是否包含指定类型的注解,若是存在返回true,不然返回false.


2、示例

(一)输出类方法上的全部注解

一、自定义的annotation

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 ;
}

二、使用自定义Annotation

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());
             }
         }
     }
}

3、@Inherited

@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);
         }
     }
}




相关文章
相关标签/搜索