参考 thinking in java 4th
概念
注解(也被称为元数据),为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个日志文件系统非常方便地使用这些数据。
java5内置了三种定义在java.lang中的注解:
@override 表示当前方法将覆盖超类中的方法
@Deprecated 使用该注解后编辑器会发出警告
@SuppressWarining 将不当的警告关闭
定义注解
1.元注解:定义注解时,会需要一些元注解,可以理解为注解的最基础的单位,java的元注解如下所示:
2.元素:在注解中,一般都会包括一些元素以表示某些值当分析处理注解时,可以利用这些值。注解的元素看起来像是接口的方法,唯一的区别是你可以为其指定默认值。注解元素的可用类型如下:
- 所有基本类型(int,float,boolean)
- String
- Class
- enum
- Annotation
- 以上类型的数组
*没有元素的注解称为标记注解
*如果使用其他类型,编译器会报错
举个例子,以下是一个简单的注解,该注解包含一个元素:name,该元素有一个default值:annoy,代码如下:
package annotation.person;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by zuzhaoyue on 18/5/21.
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Person {
public String name() default "annoy";
}
3.使用
注解的使用表现为键值对的形式,示例如下:
package annotation.person;
import annotation.person.Person;
/**
* Created by zuzhaoyue on 18/5/21.
*/
public class PersonUtils {
@Person(name = "肉肉")
private String employee;
@Person(name = "虎虎侠")
private String boss;
private String lolo;
}
编写注解处理器
如果没有用来读取注解的工具,那注解和注释就差不多了。使用注解的过程中,很重要的一部分就是创建与使用注解处理器。下面是一个简单的注解处理器,我们用它来读取PersonUtil类,并用反射机制的getAnnotation()方法来查找@Person标记,代码如下:
package annotation.person;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by zuzhaoyue on 18/5/21.
*/
public class PersonTracker {
public static void track(List<String> names, Class clazz){
for(Field field:clazz.getDeclaredFields()){
Person person = field.getAnnotation(Person.class);
if(person != null){
System.out.println("找到名叫" + person.name() + "的人!他是一名" + field.getName());
names.remove(person.name());
}
}
if(names != null && names.size() > 0){
for(String name : names){
System.out.println("没找到名叫" + name + "的人~");
}
}
}
public static void main(String args[]){
List<String> names = new ArrayList<>();
Collections.addAll(names,"肉肉","大扣","虎虎侠");
track(names, PersonUtils.class);
}
}
这个程序用了两个反射方法:getDeclaredFields()和getAnnotation(),整体思路很清晰:
1.利用java反射获得PersonUtil类的所有field
2.遍历PersonUtil的field,找到有注解为person的field,然后打印出来,并将它从总的name list中删除
3.打印剩下的没找到的名称
测试
执行PersonTracker的main()方法,控制台显示如下:
调试成功