JVM5.0定义了4个标准的元注解:html
做用:用于描述注解的使用范围
取值ElementType有:java
举例:api
@Target(ElementType.TYPE) public @interface Table { /** * 数据表名称注解,默认值为类名称 * @return */ public String tableName() default "className"; } @Target(ElementType.FIELD) public @interface NoDBColumn { }
注解Table能够用于注解类、接口(包括注解类型)或enum声明,而注解NoDBColumn仅用于注解类的成员变量。数组
做用:用于描述注解的生命周期
取值RetentionPolicy有:oracle
举例:app
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { public String name() default "fieldName"; public String setFuncName() default "setField"; public String getFuncName() default "getField"; public boolean defaultDBValue() default false; }
Column注解的的RetentionPolicy的属性值是RUNTIME,这样注解处理器能够经过反射,获取到该注解的属性值,从而去作一些运行时的逻辑处理ide
做用:用于描述其它类型的annotation应该被做为被标注的程序成员的公共API,所以能够被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。工具
举例:ui
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Column { public String name() default "fieldName"; public String setFuncName() default "setField"; public String getFuncName() default "getField"; public boolean defaultDBValue() default false; }
@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。若是一个使用了Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。this
注意:Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
当Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API加强了这种继承性。若是咱们使用java.lang.reflect去查询一个Inherited annotation类型的annotation时,反射代码检查将展开工做:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。
实例代码:
@Inherited public @interface Greeting { public enum FontColor{ BULE,RED,GREEN}; String name(); FontColor fontColor() default FontColor.GREEN; }
定义注解格式:
public @interface 注解名(定义体)
注解参数的可支持数据类型:
自定义注解的定义和具体实现能够见下一章节。
建立注解处理器,利用反射对注解加以处理。
AnnotatedElement 接口是全部程序元素(Class、Method和Constructor)的父接口,关于AnnotatedElement点详细信息能够参考
JavaDoc:Interface AnnotatedElement。
因此程序经过反射获取了某个类的AnnotatedElement对象以后,程序就能够调用该对象的以下四个个方法来访问Annotation信息:
<T extends Annotation> T getAnnotation(Class<T> annotationClass):
返回改程序元素上存在的、指定类型的注解,若是该类型注解不存在,则返回null。
方法2:Annotation[] getAnnotations():返回该程序元素上存在的全部注解。
方法3:boolean is AnnotationPresent(Class annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,不然返回false.
方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的全部注释。与此接口中的其余方法不一样,该方法将忽略继承的注释。(若是没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者能够随意修改返回的数组;这不会对其余调用者返回的数组产生任何影响。
举例:
1.FruitName
package annotation; 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 FruitName { String value() default ""; }
2.FruitColor
package annotation; 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 FruitColor { public enum Color{BlUE, RED, GREEN}; Color fruitColor() default Color.GREEN; }
3.FruitProvider
package annotation; 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 ""; }
package annotation; import annotation.FruitColor.Color; public class Apple { @FruitName("Apple") private String appleName; @FruitColor(fruitColor=Color.RED) private String appleColor; @FruitProvider(id=1, name="红富士集团", address="红富士大厦") private String appleProvider; public String getAppleName() { return appleName; } public void setAppleName(String appleName) { this.appleName = appleName; } public String getAppleColor() { return appleColor; } public void setAppleColor(String appleColor) { this.appleColor = appleColor; } public String getAppleProvider() { return appleProvider; } public void setAppleProvider(String appleProvider) { this.appleProvider = appleProvider; } public void display(){ System.out.println("The fruit name is:" + appleName + ", its color is: " + appleColor + "."); } }
package annotation; import java.lang.reflect.Field; public class FruitInfoUtil { public static void getFruitInfo(Class<?> clazz){ String strFruitName= "水果名称: "; String strFruitColor= "水果颜色: "; String strFruitProvider= "供应商信息: "; Field[] fields = clazz.getDeclaredFields(); for(Field field : fields){ if (field.isAnnotationPresent(FruitName.class)){ FruitName fruitName = (FruitName)field.getAnnotation(FruitName.class); strFruitName += fruitName.value(); System.out.println(strFruitName); } if (field.isAnnotationPresent(FruitColor.class)){ FruitColor fruitColor = (FruitColor)field.getAnnotation(FruitColor.class); strFruitColor += fruitColor.fruitColor().toString(); System.out.println(strFruitColor); } if (field.isAnnotationPresent(FruitProvider.class)){ FruitProvider fruitProvider = (FruitProvider)field.getAnnotation(FruitProvider.class); strFruitProvider += " 供应商编号:" + fruitProvider.id() + " 供应商名称:" + fruitProvider.name() + " 供应商地址:" + fruitProvider.address(); System.out.println(strFruitProvider); } } } }
执行结果:
水果名称: Apple 水果颜色: RED 供应商信息: 供应商编号:1 供应商名称:红富士集团 供应商地址:红富士大厦