java-基础-注解
一. 元注解
元注解
- @Target
- @Retention
- @Documented
- @Inherited
@Target
说明修饰范围
用于描述注解的使用范围,被描述的注解可以用在什么地方;
ElementType取值:
- CONSTRUCTOR:用于描述构造器
- FIELD:成员变量
- LOCAL_VARIABLE:用于描述局部变量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述参数
- TYPE:用于描述类、接口(包括注解类型) 或enum声明
 例子:
@Target(ElementType.TYPE)
public @interface Table {
    public String tableName() default "className";
}
@Target(ElementType.FIELD)
public @interface NoDBColumn {
}
Retention
RetentionPoicy取值
- SOURCE:在源文件中有效(即源文件保留)
- CLASS:在class文件中有效(即class保留)
- RUNTIME:在运行时有效(即运行时保留)
 例子:
@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;
}
设置为RUTIME,可以利用反射获取属性值
@Documented
@Documented描述的注解,会被写入文档
@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的子类。
利用反射查询@Inherited注解时,会检查这个类及其父类 ,直到发现@Inherited为止
定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface myAnnotation {
    String value() default "";
}
父类使用注解:
@myAnnotation
public class Father {
    private String name;
    private String age;
}
子类继承父类
public class Sun extends Father { 
}
可以通过getAnnotations方法,在子类中找到继承的注解;
getDeclaredAnnotations方法获取不到;
   for (Annotation annotation : Sun.class.getAnnotations()) {
        System.out.println(annotation);
    }
二. 自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节;
注解中的方法,是一项配置,方法名是参数名,返回值是参数值,可以通过default来声明参数的默认值;
参数设定:
- 只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;
- 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;
- 如果只有一个参数成员,最好把参数名称设为"value",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。
只有一个参数:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
    String value() default "";
}
带枚举的例子:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
    public enum Color{ BULE,RED,GREEN};
    Color fruitColor() default Color.GREEN;
}
使用注解:
public class Apple {
    @FruitName("Apple")
    private String appleName;
    @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("水果的名字是:苹果");
    }
}
注解的默认值
注解的值可以在定义时或者使用时指定;
注解元素的值不可为null,所以常使用空串和0,用空串和负数表示不存在;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitProvider {
    public int id() default -1;
    public String name() default "";
    public String address() default "";
}
三. 注解处理
定义为RUNTIME才能获取
AnnotatedElement 接口是所有注解的父接口,获取某个类的AnnotatedElement对象后,调用对象的以下四个方法,访问Annotation信息
- getAnnotation:返回指定类型注解
- Annotation[] getAnnotations:返回所有注解
- isAnnotationPresent:是否含有指定类型注解
- Annotation[] getDeclaredAnnotations:返回有所注解,忽略Inherited的注解
注解测试例子:
 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);
            }
        }
 
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号