java自定义注解

本文介绍了如何在Java中创建和使用自定义注解,包括定义注解、添加业务属性、具体使用案例以及通过反射获取注解信息和字段值。还讨论了注意事项,如字段访问权限和反射顺序,并提出了通过枚举优化值处理的方案,展示了如何根据注解处理不同类型的数据。
摘要由CSDN通过智能技术生成

目录

 创建注解文件

  添加注解

  添加想要的业务属性

   具体使用

  获取属性信息

  获取属性和字段值

注意事项


 创建注解文件

  添加注解

@Target(ElementType.FIELD)//只能定义在字段上
// @Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)//在运行时有效
public @interface DynamicAnnotation {
    
}

  添加想要的业务属性

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

    String description();

    String field();

    //值是否需要再次处理
    boolean isValue();

    int sort();
}

   具体使用

@DynamicAnnotation(description = "车辆所在省份", field = "carProvinceName", isValue = false, sort = 6)
public String carProvinceName;

  获取属性信息

/**
     * 获取某类实体的DynamicAnnotation注解信息
     * 返回map
     *
     * @param object
     * @param headerMap
     * @return
     */
    private <T> void getAnnotationMsg(T object, Map<String, String> headerMap) {
        Map<Integer, String> map = new HashMap();
        
        for (Field field : object.getClass().getFields()) {
            //getDeclaredFields只能取到子类属性,不包含父类属性
            //判断该字段是否存在DynamicAnnotation注解
            if (field.isAnnotationPresent(DynamicAnnotation.class)) {
                DynamicAnnotation myAnnotation = field.getAnnotation(DynamicAnnotation.class);
                System.out.println("注解属性1:["+myAnnotation.field()+"],注解属性1:["+myAnnotation.description()+"]");
            }
        }
    }

  获取属性和字段值

data.stream().forEach(a -> {

                Map<String, Object> dataMap = new LinkedHashMap<>();
                for (Field field : a.getClass().getDeclaredFields()) {
                    //判断该字段是否存在MyAnnotation注解
                    if (field.isAnnotationPresent(DynamicAnnotation.class)) {
                        field.setAccessible(true);
                        DynamicAnnotation myAnnotation = field.getAnnotation(DynamicAnnotation.class);
                        // ((AnnotationInvocationHandler) ((Proxy) myAnnotation).h).memberValues
                        System.out.println("字段:["+myAnnotation.field()+"],字段值:["+field.get(a)+"]");
                    }
                }

注意事项

1.注意public和private的区别:getDeclaredFields()和getFields()的区别。

后者能取到继承的父类属性

2.如果,需要反射的类中有继承关系,顺序会按照先子类后父类的关系进行反射;

如果要指定顺序,需要新加一个排序的属性


优化方案

以上为我的初步方案,代码审核时候,领导给了建议,针对isValue字段可以进一步处理,搞一个

数据转换器,比如:时间类型转年月日,布尔转是否等,给了我灵感,于是进行了一下更改。

首先,isValue中自定义属性之前规定的是布尔类型,改为枚举类

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

    String description();

    String field();

    /**
     * 处理值
     *
     * @return
     */
    DynamicValueEnum isValue() default DynamicValueEnum.NULL;

    int sort();

}

  枚举类

@AllArgsConstructor
@Getter
public enum DynamicValueEnum {

    NULL,

    BOOL_HANDLE,

    OUTSIDE_HANDLE;
}

  在处理非必要填写的属性时候,可以用default关键字给一个默认值,这样在使用自定义注解时

  候,可以忽略对此属性的赋值,使用如下:

@DynamicAnnotation(description = "定位是否与经销商所在地一致", field = "isSame", isValue = DynamicValueEnum.BOOL_HANDLE, sort = 8)
    public boolean isSame;

@DynamicAnnotation(description = "报终端时间", field = "alarmPermanent", sort = 9)
    public String alarmPermanent;

 具体的类型值处理,在反射里进行了

/**
     * 获取某字段值
     *
     * @param object
     * @param dataMap
     * @param <T>
     */
    private <T> void getObjectFiledValue(T object, Map<String, Object> dataMap) {
        try {
            for (Field field : object.getClass().getFields()) {
                if (field.isAnnotationPresent(DynamicAnnotation.class)) {
                    field.setAccessible(true);
                    DynamicAnnotation myAnnotation = field.getAnnotation(DynamicAnnotation.class);
                    //字段与value放入map中
                    if (myAnnotation.isValue() == DynamicValueEnum.NULL) {
                        dataMap.put(myAnnotation.field(), field.get(object));
                    } else if (myAnnotation.isValue() == DynamicValueEnum.BOOL_HANDLE) {
                        dataMap.put(myAnnotation.field(), (boolean) field.get(object) ? "是" : "否");
                    }
                }
            }
        } catch (IllegalAccessException e) {
            return;
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值