转载自:http://blog.youkuaiyun.com/pzw_0612/article/details/54089793
http://blog.youkuaiyun.com/pzw_0612/article/details/54089919
元注解:
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
1.@Target
2.@Retention,
3.@Documented,
4. @Inherited,允许子类继承父类的注解
这些类型和它们所支持的类在java.lang.annotation包中可以找到。
@Target
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
取值(java.lang.annotation.ElementType)有:
1. TYPE:用于描述类、接口(包括注解类型) 或enum声明
2. FIELD:用于描述域
3. METHOD:用于描述方法
4. PARAMETER:用于描述参数
5. CONSTRUCTOR:用于描述构造器
6. …
@Retention:定义了该Annotation被保留的时间长短。
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
取值(java.lang.annotation.RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
Retention meta-annotation类型有唯一的value作为成员,它的取值来自java.lang.annotation.RetentionPolicy的枚举类型值。
@Documented:
用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,表示注解会被包含在javaapi文档中。
使用实例:
自定义两个注解
AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象之后,程序就可以调用该对象的如下四个个方法来访问Annotation信息:
方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
方法2:Annotation[] getAnnotations():返回该程序元素上存在的所有注解。
方法3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
测试
关于java8新增的注解相关的可以参考:http://9leg.com/java/2016/01/21/java-annotation.html
http://blog.youkuaiyun.com/pzw_0612/article/details/54089919
元注解:
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
1.@Target
2.@Retention,
3.@Documented,
4. @Inherited,允许子类继承父类的注解
这些类型和它们所支持的类在java.lang.annotation包中可以找到。
@Target
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
取值(java.lang.annotation.ElementType)有:
1. TYPE:用于描述类、接口(包括注解类型) 或enum声明
2. FIELD:用于描述域
3. METHOD:用于描述方法
4. PARAMETER:用于描述参数
5. CONSTRUCTOR:用于描述构造器
6. …
@Retention:定义了该Annotation被保留的时间长短。
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
取值(java.lang.annotation.RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
Retention meta-annotation类型有唯一的value作为成员,它的取值来自java.lang.annotation.RetentionPolicy的枚举类型值。
@Documented:
用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,表示注解会被包含在javaapi文档中。
使用实例:
自定义两个注解
/**
* 水果名称
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
String value() default "fruit";
}
/**
* 水果颜色
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
/**
* 颜色枚举
*
*/
public enum Color{ BULE,RED,GREEN};
/**
* 颜色属性
* @return
*/
Color fruitColor() default Color.GREEN;
}
使用注解public class Apple {
@FruitName("Apple")//只用是value()方法才可以省略value =
private String appleName;
@FruitColor(fruitColor = FruitColor.Color.RED)
private String appleColor;
public void setAppleColor(String appleColor) {
this.appleColor = appleColor;
}
public String getAppleColor() {
return appleColor;
}
public void setAppleName(String appleName) {
this.appleName = appleName;
}
public String getAppleName() {
return appleName;
}
public void displayName() {
System.out.println("水果的名字是:" + getAppleName() + " , 颜色是: " + getAppleColor());
}
}
采用java.lang.reflect 包所提供的反射API读取运行时Annotation信息。当一个Annotation类型被定义为运行时的Annotation后,该注解才能是运行时可见,当class文件被装载时被保存在class文件中的Annotation才会被虚拟机读取。AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象之后,程序就可以调用该对象的如下四个个方法来访问Annotation信息:
方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
方法2:Annotation[] getAnnotations():返回该程序元素上存在的所有注解。
方法3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
测试
//Class clazz = Apple.class;
Apple apple = new Apple();
Class clazz = apple.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(FruitName.class)) {
FruitName fruitName = field.getAnnotation(FruitName.class);
System.out.println("水果名称:" + fruitName.value());
} else if (field.isAnnotationPresent(FruitColor.class)) {
FruitColor fruitColor = field.getAnnotation(FruitColor.class);
System.out.println("水果颜色:" + fruitColor.fruitColor());
}
}
apple.displayName();//Class clazz = Apple.class;
Apple apple = new Apple();
Class clazz = apple.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(FruitName.class)) {
FruitName fruitName = field.getAnnotation(FruitName.class);
System.out.println("水果名称:" + fruitName.value());
} else if (field.isAnnotationPresent(FruitColor.class)) {
FruitColor fruitColor = field.getAnnotation(FruitColor.class);
System.out.println("水果颜色:" + fruitColor.fruitColor());
}
}
apple.displayName();
运行结果:水果名称:Apple
水果颜色:RED
水果的名字是:null , 颜色是: null
关于java8新增的注解相关的可以参考:http://9leg.com/java/2016/01/21/java-annotation.html