1. 定义一个注解:FruitProvider.java
package com.fukaiit;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
public int id() default -1;
public String name() default "";
public String address() default "";
}
说明:
- 参数成员只能用public或默认(default)这两个访问权修饰
- 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组。
- 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法。
- 这里使用到了元注解。
java.lang.annotation提供了四种元注解,专门注解其他的注解(在自定义注解的时候使用):- @Documented –注解是否将包含在JavaDoc中
- @Retention –什么时候使用该注解,注解的生命周期
RetentionPolicy.SOURCE
: 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override,@SuppressWarnings都属于这类注解。RetentionPolicy.CLASS
: 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式RetentionPolicy.RUNTIME
: 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
- @Target –注解用于什么地方,默认值为任何元素
ElementType.CONSTRUCTOR
: 用于描述构造器ElementType.FIELD
: 成员变量、对象、属性(包括enum实例)ElementType.LOCAL_VARIABLE
: 用于描述局部变量ElementType.METHOD
: 用于描述方法ElementType.PACKAGE
: 用于描述包ElementType.PARAMETER
: 用于描述参数ElementType.TYPE
: 用于描述类、接口(包括注解类型) 或enum声明
- @Inherited – 是否允许子类继承该注解
如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
2. 编写一个注解处理器:FruitInfoUtil.java
package com.fukaiit;
import java.lang.reflect.Field;
public class FruitInfoUtil {
public static void getFruitInfo(Class<?> clazz){
String fruitProvider ="供应商信息:";
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(FruitProvider.class)) {
FruitProvider tempFruitProvider =field.getAnnotation(FruitProvider.class);
fruitProvider = fruitProvider+"供应商编号:"+tempFruitProvider.id()+",供应商姓名:"+tempFruitProvider.name()+",供应商地址:"+tempFruitProvider.address();
System.out.println(fruitProvider);
}
}
}
}
3. 定义一个Apple类,使用注解:Apple.java
package com.fukaiit;
public class Apple {
@FruitProvider(id=10,name="山西红富士集团",address="陕西省西安市")
private String provider;
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
}
4. 测试看看:Test.java
package com.fukaiit;
public class Test {
public static void main(String[] args) {
FruitInfoUtil.getFruitInfo(Apple.class);
}
}
运行结果:
5. 总结-思维导图
转自深入理解Java:注解(Annotation)–注解处理器
References
[1] 注解Annotation实现原理与自定义注解例子
[2] 深入理解Java:注解(Annotation)–注解处理器