java @interface自定义注解和通过反射获取注解属性值

@interface

@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。
方法的名称就是参数的名称,返回值类型就是参数的类型
参数类型只能是基本类型、Class、String、enum。
可以通过default来声明参数的默认值。
Java注解就是一种特殊的接口,使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,因此在自定义注解时不能继承其他的注解或者接口。

注解的应用

  1. 生成文档。如@param @return 等
  2. 替代配置文件功能。如spring2.5开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量
  3. 在编译时进行格式检查。如@Override

自定义注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ProductAnnotation {

    //类型枚举
    public enum Type{ 手机,电脑,平板};
    //商品类型
    Type productType() default Type.手机;
    //商品发布时间
    String publishYear() default "";
    //商品名称
    String productName() default "";

}

Target 指明该类型的注解可以注解的元素范围,主要包括以下几种参数类型:

ElementType.TYPE 用于类,接口,枚举,但不能是注解
ElementType.FIELD 作用于字段,包含枚举值
ElementType.METHOD 作用于方法,不包含构造方法
ElementType.PARAMETER 作用于方法的参数
ElementType.CONSTRUCTOR 作用于构造方法
ElementType.LOCAL_VERIABLE 作用于本地变量或者catch语句
ElementType.ANNOTATION_TYPE 作用于注解
ElementType.PACKAGE 作用于包

Retention 指明在什么级别显示此注解,主要包括以下几种参数类型:

RetentionPolicy.SOURCE 注解存在于源代码中,编译时会被抛弃
RetentionPolicy.CLASS 注解会被编译到class文件中,但是JVM会忽略
RetentionPolicy.RUNTIME JVM会读取注解,同时会保存到class文件中

通过反射获取注解属性值

注解的解析依赖于反射。jdk1.5 增加了注解,也增加了读取注解的api,在java.lang.reflect包中新增了AnnotatedElement接口,JDK源码如下:

    public interface AnnotatedElement {  
            boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);  
            <T extends Annotation> T getAnnotation(Class<T> annotationClass);  
            Annotation[] getAnnotations();  
            Annotation[] getDeclaredAnnotations();  
    }  
isAnnotationPresent:判断是否标注了指定注解
getAnnotation:获取指定注解,没有则返回null
getAnnotations:获取所有注解,包括继承自基类的,没有则返回长度为0的数组
getDeclaredAnnotations:获取自身显式标明的所有注解,没有则返回长度为0的数组

通过反射获取注解属性值的例子:

public class ProductReflectAnnotation {

    @ProductAnnotation(productName="iphone X",publishYear="2017发布")
    private String iphoneX;//iponeX配上注解
    @ProductAnnotation(productType= ProductAnnotation.Type.电脑,productName="mac",publishYear="2018发布")
    private String mac;//Mac配上注解
    private String noAnnotationField;//noAnnotationField不加注解

    public static void main(String[] args) {
        // 解析ProductReflectAnnotation类属性的注解
        // getDeclaredFields方法会返回ProductReflectAnnotation类所有的属性
        Field[] fields = ProductReflectAnnotation.class.getDeclaredFields();
        for(Field field : fields){
            //判断属性是否标注了@ProductAnnotation注解
            boolean fieldHasAnno = field.isAnnotationPresent(ProductAnnotation.class);
            if(fieldHasAnno){
                //获取@ProductAnnotation注解
                ProductAnnotation product = field.getAnnotation(ProductAnnotation.class);
                //获取@ProductAnnotation注解 参数值
                String name = product.productName();
                String publishYear = product.publishYear();
                ProductAnnotation.Type type = product.productType();
                System.out.println("[" + field.getName() + "] " + name + ","+ type + "," + publishYear);
            }
        }
    }

}

输出:

[iphoneX] iphone X,手机,2017发布
[mac] mac,电脑,2018发布
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值