Annotation,代码里的特殊标记,在编译、类加载、运行时被读取,并执行相应的处理。
使用注解,在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。
Annotation提供了一种为程序元素设置元数据的方法。
Annotation是一个接口,通过反射来获取指定程序元素的Annotation对象,通过Annotation对象来获得注解里的元数据。
Annotation不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的执行。
一、基本Annotation
-
限定重写父类方法:@Override
-
标记已过时:@Deprecated
-
抑制编译器警告:@SuppressWarnings
-
Java7的“堆污染”警告与@SafeVarargs
-
Java8的函数式接口与@FunctionallInterface
二、JDK的元Annotation
位于java.lang.annotation包下的6个Meta Annotation(元Annotation),其中有5个元Annotation用于修饰其他的Annotation定义,@Repeatable 专门用于定义Java8新增的重复注解。
1、@Retention
@Retention用于指定被修饰的Annotation可以保留多长时间。
value成员变量的值有三个:
-
RetentionPolicy .CLASS:编译器把注解记录在class文件中。
-
RetentionPolicy.RUNTIME: 编译器把注解记录在class文件中,运行Java程序时,JVM获取注解信息,程序可以通过反射获取该注解信息。
-
RetentionPolicy.SOURCE:只保留在源代码中,编译器注解丢弃。
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
...
}
2、@Target
用于被修饰的注解能用于修饰哪些程序单元。
取值 | 说明 |
---|---|
ElementType.ANNOTATION_TYPE | 给一个注解进行注解 |
ElementType.CONSTRUCTOR | 给构造方法进行注解 |
ElementType.FIELD | 给属性进行注解 |
ElementType.LOCAL_VARIABLE | 可以给局部变量进行注解 |
ElementType.METHOD | 可以给方法进行注解 |
ElementType.PACKAGE | 可以给包进行注解 |
ElementType.PARAMETEP | 可以给一个方法内的参数进行注解 |
ElementType.TYPE | 可以给一个类型进行注解,比如类,接口,枚举等 |
@Target(ElementType.TYPE)
public @interface TestAnnotation {
}
3、@Documented
用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。
@Documented
public @interface TestAnnotation {
}
4、@Inherited
指定被它修饰的注解将具有继承性——如果某个类使用了@Xxx注解(定义该注解时使用了@Inherited修饰)修饰,则其子类将自动被@Xxx修饰。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {}
@Test
public class A {}
public class B extends A {}
5、@Repeatable
Java新增的注解,允许使用多个相同类型的注解来修饰同一个类。
@interface Persons {
Person[] value();
}
@Repeatable(Persons.class)
@interface Person{
String role default "";
}
@Person(role="artist")
@Person(role="coder")
@Person(role="PM")
public class SuperMan{
}
三、自定义Annotation
1、定义Annotation
定义新的Annotation类型使用@interface
,与定义一个接口类似。
public @interface MyTag {
//定义带两个成员变量的Annotation
//Annotation中的成员变量以方法的形式来定义
String name() default "yvonne";
int age() default 25;
}
定义Annotation之后,就可以在程序的任何地方使用该Annotation。
public class AnnotationTest {
@MyTag
public void info() {
...
}
}
2、使用Annotation
/***********注解声明***************/
/**
* 水果名称注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
String value() default "";
}
/**
* 水果颜色注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
/**
* 颜色枚举
* @author peida
*
*/
public enum Color{ BULE,RED,GREEN};
/**
* 颜色属性
* @return
*/
Color fruitColor() default Color.GREEN;
}
/**
* 水果供应者注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
/**
* 供应商编号
* @return
*/
public int id() default -1;
/**
* 供应商名称
* @return
*/
public String name() default "";
/**
* 供应商地址
* @return
*/
public String address() default "";
}
/***********注解使用***************/
public class Apple {
@FruitName("Apple")
private String appleName;
@FruitColor(fruitColor=Color.RED)
private String appleColor;
@FruitProvider(id=1,name="杨倩csdn",address="https://blog.csdn.net/happyniceyq")
private String appleProvider;
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 setAppleProvider(String appleProvider) {
this.appleProvider = appleProvider;
}
public String getAppleProvider() {
return appleProvider;
}
public void displayName(){
System.out.println("水果的名字是:苹果");
}
}
/***********注解处理器***************/
public class FruitInfoUtil {
public static void getFruitInfo(Class<?> clazz){
String strFruitName=" 水果名称:";
String strFruitColor=" 水果颜色:";
String strFruitProvicer="供应商信息:";
Field[] fields = clazz.getDeclaredFields();
for(Field field :fields){
if(field.isAnnotationPresent(FruitName.class)){
FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
strFruitName=strFruitName+fruitName.value();
System.out.println(strFruitName);
}
else if(field.isAnnotationPresent(FruitColor.class)){
FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
System.out.println(strFruitColor);
}
else if(field.isAnnotationPresent(FruitProvider.class)){
FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
System.out.println(strFruitProvicer);
}
}
}
}
/***********输出结果***************/
public class FruitRun {
/**
* @param args
*/
public static void main(String[] args) {
FruitInfoUtil.getFruitInfo(Apple.class);
}
}
====================================
水果名称:Apple
水果颜色:RED
供应商编号:1 供应商名称:杨倩csdn 供应商地址:https://blog.csdn.net/happyniceyq