反射获取字段对象并修改字段内容及修改字段上面的注解信息

通过反射获取字段注解信息,并修改注解信息
需求场景:
最近在做一个excel的导出功能,excel的表头需要合并,合并后的表头是动态的,如下图所示:
在这里插入图片描述
解决方案:
1、用EasyExcel 作 excel导出,如下图所示,定义一个excel导出Vo:

@Data
// 头背景设置无填充色
@HeadStyle(fillPatternType = FillPatternType.NO_FILL)
@HeadFontStyle(fontHeightInPoints = 11)
// 内容的背景设无填充色
@ContentStyle(fillPatternType = FillPatternType.NO_FILL,borderLeft= BorderStyle.THIN,borderTop = BorderStyle.THIN,
                borderRight = BorderStyle.THIN,borderBottom = BorderStyle.THIN,verticalAlignment = VerticalAlignment.CENTER)
// 内容字体设置成20
@ContentFontStyle(fontHeightInPoints = 12)
public class AllocationProgressDetailOutRes {


    @ColumnWidth(20)
    @ExcelProperty(value = "数据类别")
    @ApiModelProperty(value = "数据类别", example = "非年卡资源包")
    private String labelType;

    @ColumnWidth(20)
    @ExcelProperty(value = "资源类型")
    @ApiModelProperty(value = "资源类型", example = "DAC-T")
    private String agentOrderType;

    @ColumnWidth(20)
    @ExcelProperty(value = "资源包名称")
    @ApiModelProperty(value = "资源包名称", example = "购买DAC-T计划资源包")
    private String agentOrderDesc;
    @ColumnWidth(20)
    @ExcelProperty(value = {"累计","购买"})
    @ApiModelProperty(value = "累计购买", example = "11")
    private Long totalPurchase;

    @ColumnWidth(20)
    @ExcelProperty(value = {"累计","赠送"})
    @ApiModelProperty(value = "赠送", example = "11")
    private Long totalGive;

    @ColumnWidth(20)
    @ExcelProperty(value = {"累计","未分配"})
    @ApiModelProperty(value = "未分配", example = "11")
    private Long totalNotMatch;

    @ColumnWidth(20)
    @ExcelProperty(value = {"累计","退单"})
    @ApiModelProperty(value = "退单", example = "11")
    private Long totalBackSvOrder;

    @ColumnWidth(20)
    @ExcelProperty(value = {"累计","已分配"})
    @ApiModelProperty(value = "已分配", example = "11")
    private Long totalMatched;

    @ColumnWidth(20)
    @ExcelProperty(value = {"当前业务月","购买"})
    @ApiModelProperty(value = "购买", example = "11")
    private Long currentMonthPurchase;

    @ColumnWidth(20)
    @ExcelProperty(value ={"当前业务月","赠送"})
    @ApiModelProperty(value = "赠送", example = "11")
    private Long currentMonthGive;

    @ColumnWidth(20)
    @ExcelProperty(value = {"当前业务月","未分配"})
    @ApiModelProperty(value = "未分配", example = "11")
    private Long currentMonthNotMatch;


    @ColumnWidth(20)
    @ExcelProperty(value = {"当前业务月","退单"})
    @ApiModelProperty(value = "退单", example = "11")
    private Long currentMonthBackSvOrder;

    @ColumnWidth(20)
    @ExcelProperty(value = {"当前业务月","已分配"})
    @ApiModelProperty(value = "已分配", example = "11")
    private Long currentMonthMatched;

2、想办法拿到 @ExcelProperty 注解对象,并把value值给修改掉
3、具体代码如下:

        Class<AllocationProgressDetailOutRes> clazz = AllocationProgressDetailOutRes.class;
        Field[] fields = clazz.getDeclaredFields();
        for (AllocationProgressDetailHeadRes headRes : headList) {
            String mergeColumn = headRes.getColumnName();
            String text = headRes.getText();
            for (Field field : fields) {
                String fieldName = field.getName();
                if (fieldName.startsWith(mergeColumn)) {
                    ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
                    //原来的数组
                    String[] value = annotation.value();
                    InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
                    try {
                        Field annotationField = invocationHandler.getClass().getDeclaredField("memberValues");
                        annotationField.setAccessible(true);
                        Map map = (Map) annotationField.get(invocationHandler);
                        String[] newValue = {text, value[1]};
                        map.put("value", newValue);
                    } catch (Exception e) {
                        log.error("通过反射修改表头内容失败", e);
                    }
                }
            }
        }

(我这里面的headList 是一个动态的表头集合),通过上述方法后,即可动态修改注解里面的内容,然后也可以实现表头的合并。
----------------------------------手动分割线----------------------------------
下面介绍,如何用反射,比较两个对象里面每个字段的值,并修改对象1的值:

    private void compareData(ReportAllocationProgressOverallTableMo currentData,ReportAllocationProgressOverallTableMo lastDayData) {
        if (EmptyUtils.isEmpty(lastDayData)) {
            //之前的历史数据是空的
            return;
        }
        Class<ReportAllocationProgressOverallTableMo> clazz = ReportAllocationProgressOverallTableMo.class;
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            Class<?> type = field.getType();
            //这个是判断这个字段类型是否是ReportFieldBean类型
            if (type.isAssignableFrom(ReportFieldBean.class)) {
            	//设置true代表可以访问这个field字段对象
                field.setAccessible(true);
                try {
                    Object obj = field.get(currentData);
                    if (EmptyUtils.isEmpty(obj)) {
                        continue;
                    }
                    ReportFieldBean filedObj = (ReportFieldBean) field.get(currentData);
                    if (EmptyUtils.isNotEmpty(filedObj) && EmptyUtils.isNotEmpty(filedObj.getFieldValue())) {
                        Long fieldValue = filedObj.getFieldValue();
                        int flag = getFlag(fieldValue, lastDayData, field);
                        //重新设置flag,重新修改currentData对象的值
                        field.set(currentData, new ReportFieldBean(fieldValue, flag));
                    }
                } catch (Exception e) {
                    log.error("反射异常", e);
                }
            }
        }
    }
            


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个技术问题,我可以为您提供一些信息。在Java中,要获取注解信息可以使用反射机制。首先需要获取类的Class对象,然后通过这个对象获取到指定方法或字段上的注解对象。可以使用Annotation接口的实现类来获取注解信息,再使用反射机制修改注解内容。下面是一个简单的示例代码: ```java // 定义一个注解类 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { String value() default "原始值"; } // 在方法上使用注解 public class MyClass { @MyAnnotation("Hello, World!") public void myMethod() { System.out.println("My method."); } } // 反射获取注解修改内容 Class myClass = MyClass.class; Method myMethod = myClass.getMethod("myMethod"); MyAnnotation myAnnotation = myMethod.getAnnotation(MyAnnotation.class); String oldValue = myAnnotation.value(); System.out.println("原始值:" + oldValue); // 修改注解内容 MyAnnotation newAnnotation = new MyAnnotation() { public String value() { return "新值"; } public Class<? extends Annotation> annotationType() { return MyAnnotation.class; } }; Method method = myClass.getDeclaredMethod("myMethod"); // 获取该方法上的注解 Annotation annotation = method.getAnnotation(MyAnnotation.class); // 获取 AnnotationInvocationHandler 实例 InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation); // 获取 memberValues 字段 Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues"); // 取消 Java 语言访问检查以访问私有字段 memberValues.setAccessible(true); // 修改注解的值 Map<String, String> values = (Map<String, String>) memberValues.get(invocationHandler); values.put("value", newAnnotation.value()); String newValue = myMethod.getAnnotation(MyAnnotation.class).value(); System.out.println("新值:" + newValue); ``` 上述代码示例中,我们定义了一个名为“MyAnnotation”的注解,并在MyClass类的myMethod()方法上使用了该注解。然后,我们使用反射机制获取myMethod()方法上的注解对象,并修改注解内容。最后,我们再次获取注解对象内容,验证注解内容已被修改

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值