转载请注明出处:https://www.cnblogs.com/zhizaixingzou/p/10023808.html
目录
1. 注解
1.1. 什么是注解
注解是描述源代码的元数据,和业务逻辑无关。例如@Override使用如下:
即使不使用@Override也没有问题,但写了它就明明白白地告诉编译器,这是个重写方法,父类中需要有这个方法才行,没有则编译器会报错。可以看到它有两个好处:一是更易读,看到它就知道父类中有定义它,二是如果我们写错了方法名,则编译器报错,从而提醒我们方法编写有问题了。
1.2. 为什么引入注解
之前,XML被广泛应用于配置,与代码达到松耦合的效果。
但如果希望描述数据例如把方法声明为服务,这时使用注解更好,和代码紧耦合。此外,注解还是一种描述数据的标准方式,不像接口、注释、transient等各自为政。
使用注解最大的好处在于描述了程序,然后注解消费器,通常是框架,就可以利用反射读取它,并做一定的处理,动态地控制程序的逻辑,从而造就了框架的灵活和强大。
1.3. 自定义注解
注解的所有属性都被定义成不带参数的方法,并允许提供默认值,类型为基本类型、String、枚举、注解或它们的数组(支持注解属性的注解为容器注解,容器注解的保留期必须不短于注解属性)。
使用该注解时可以在方法定义前写上:
@Todo(priority = Todo.Priority.MEDIUM, author = "Yashwant", status = Todo.Status.STARTED)
如果属性只有一个,则可以命名为value,使用时无需再标明属性名。
1.4. 元注解
包java.lang.annotation下提供了4种元注解,专门用来注解其他注解。
1)@Documented,用来说明被注解的注解是否将包含在Java文档中,如该注解注解了某个类的方法,那么在文档中,该方法的描述上注解会原样保留。
2)@Inherited,用来说明是否允许被(被@Inherited注解的注解)注解的类的子类继承该注解。
3)@Retention,用来说明注解保留到什么阶段。
其中,RetentionPolicy是一个枚举类型,值有SOURCE,CLASS,RUNTIME,SOURCE表示该注解能为编译器等源码解析类的消费器解读(可以利用它生成自动代码,如Lombok项目),解读后抛弃,不进入字节码,@Override和@SuppressWarnings就是。CLASS,默认是这种方式(即没有对注解用@Retention注解的情况下),在字节码中有保留,在类加载过程中被解读,完后被抛弃。RUNTIME,一直保留直到JVM中可以解读,在JVM中通常是通过反射来读取定义的注解,然后根据注解的属性值,完成代码的行为,我们自定义的注解一般就是这种情况,@Deprecated也是。
4)@Target,用来说明注解应用在什么地方,默认可以任何ElementType。
ElementType.TYPE,用于描述类、接口、注解或enum。
ElementType.FIELD,用于描述字段、枚举常量。
ElementType.METHOD,用于方法。
ElementType.PARAMETER,用于参数。
ElementType.CONSTRUCTOR,用于构造方法。
ElementType.LOCAL_VARIABLE,用于局部变量。
ElementType.ANNOTATION_TYPE,用于注解。
ElementType.PACKAGE,用于包。
1.5. 容器注解
容器注解的使用如下:
1.6. @Override、@Deprecate和@SuppressWarnings的应用场景
子类用@Override是一个好习惯,可以防止潜在的未能复写。
可是有一天发现work方法并不恰当,比如命名不够好,需要用另外的代替。我们想把这个方法在接口上删了,但有类已经实现了它,不能这么粗暴好么。于是,我们用了:
后面有人实现接口时,就会感受到它过时了,用时编译器会告警。已用的,我们不想编译器告警,那么:
1.7. 注解消费器
注解是一种元数据,和业务逻辑无关。但要发挥作用,则需要注解消费器读取它的信息,并实现必要的处理逻辑,例如,如果@Override了一个没有的方法,编译器会报错,编译器就是@Override的消费器,或者说注解的用户。特别地,我们可以根据编译过程或执行过程中的消费器接口产生作用。
对于自定义的Todo注解,我们可以定义一个消费器,如下:
输出如下:
1.8. 解决什么问题
1.8.1. 模仿JUnit框架
模拟@Test注解:
模拟@Test(Exception.class):
1.8.2. 通过注解给私有字段赋值新创建对象
一般做法:
新做法:
1.8.3. 向编译器注册自己的注解处理器
这里讨论的注解处理器,将是一个在javac中用来编译时扫描和处理注解的工具。可以为特定的注解,注册你自己的注解处理器。
1.9. 参考资料
http://www.importnew.com/10294.html
http://www.importnew.com/24051.html
http://www.importnew.com/17524.html