注解解析

参考该文章:http://www.cnblogs.com/mouseIT/p/5033746.html
作者补充了注解解析

注解格式

@Documented
@Inherited
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
//定义注解类
public @interface Book{
    //定义Book的书名
    String bookname();
    //定义Book的价格,默认99.9
    Double price() default 99.9;
    //定义作者数组,其中
    String[] authors();
}

详解

元注解

  • @Target 注释的使用位置.
  • @Retention 注解的声明周期.
  • @Documented
  • @Inherited 被该注解标记类的,子类都继承该注解

@Target

  • 作用:指明此注解用在哪个位置,如果不写默认是任何地方都可以使用。
    • 可选的参数值在枚举类ElemenetType中包括:
 TYPE: 用在类,接口上
 FIELD:用在成员变量上
 METHOD: 用在方法上
 PARAMETER:用在参数上
 CONSTRUCTOR:用在构造方法上
 LOCAL_VARIABLE:用在局部变量上
 

@Retention

  • 作用:定义该注解的生命周期(有效范围)。
    • 可选的参数值在枚举类型RetentionPolicy中包括
SOURCE:注解只存在于Java源代码中,编译生成的字节码文件中就不存在了。
CLASS:注解存在于Java源代码、编译以后的字节码文件中,运行的时候内存中没有,默认值。
RUNTIME:注解存在于Java源代码中、编译以后的字节码文件中、运行时内存中,程序可以通过反射获取该注解。【常用】

@Inherited:

@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。

当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。

@Documented:

该属性用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。

注解类的成员属性

注解参数的可支持数据类型:

  • 1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
  • 2.String类型
  • 3.Class类型
  • 4.enum类型
  • 5.Annotation类型
  • 6.以上所有类型的数组

Annotation类型里面的参数该怎么设定:

第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;

第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;

第三,如果只有一个参数成员,最好把参数名称设为"value",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。

对注解的解析

  • 在对注解类进行确定之后,便是解析注解
原理

通过反射,拿到注解类的class字节码文件,再获取到注解类的属性

  • 什么是注解解析

  • 通过Java技术获取注解数据的过程则称为注解解析。

与注解解析相关的接口

Anontation:所有注解类型的公共接口,类似所有类的父类是Object。

AnnotatedElement:定义了与注解解析相关的方法,常用方法:

boolean isAnnotationPresent(Class annotationClass); 判断当前对象是否有指定的注解,有则返回true,否则返回false。

T getAnnotation(Class annotationClass); 获得当前对象上指定的注解对象。

3.5.3 获取注解数据的原理

  • 注解作用在那个成员上,就通过反射获得该成员的对象(Filed)来得到它的注解。

  • 如注解作用在方法上,就通过方法(Method)对象得到它的注解*

  • 如注解作用在类上,就通过Class对象得到它的注解

//对类进行注解  ElementType.TYPE
@Book(value = "西游记1", price=9988, authors = {"吴承恩1", "白求恩1"})
public class BookShelf {

    private int id;
    
    //对方法进行注解  ElementType.METHOD
    @Book(value = "西游记", price = 998, authors = {"吴承恩", "白求恩"})
    public void show() {
        //定义变量
        String value = "";
        int price = 0;
        String[] authors = {};

        //获取当前类的Class对象
        Class<? extends BookShelf> cls = this.getClass();
        try {
            //获取当前方法对象
            Method show = cls.getMethod("show");
            //判断当前方法上是否有注解
            if (show.isAnnotationPresent(Book.class)) {
                Book book = show.getAnnotation(Book.class);
                value = book.value();
                price = book.price();
                authors = book.authors();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("书名为 : " + value);
        System.out.println("价格为 : " + price);
        System.out.println("作者为 : " + Arrays.toString(authors));
    }
}

Test1

class Test1 {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf();
        bookShelf.show();
    }
}

Test2

public class Test2 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> cls = Class.forName("DataSource.BookShelf");
        if(cls.isAnnotationPresent(Book.class)){
            Book book = cls.getAnnotation(Book.class);
            String value = book.value();
            int price = book.price();
            String[] authors = book.authors();
            System.out.println("value = " + value);
            System.out.println("price = " + price);
            System.out.println("authors = " + Arrays.toString(authors));
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值