You need to enable JavaScript to run this app. Java中如何对POJO所有带指定注解的字段统一应用过滤器修改值
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何对POJO所有带指定注解的字段统一应用过滤器修改值

最优实现方案

你遇到的栈溢出基本是递归处理嵌套POJO时碰到了循环引用(比如Pojo实例持有SubPojo,SubPojo实例又反向持有外层Pojo),或者没有限制递归边界导致的无限递归。

核心实现思路

  • 引入已访问对象集合,基于对象引用判断是否已经处理过,避免循环递归
  • 字段处理分两类:符合要求的@AnnotatedProp注解String字段直接执行过滤逻辑,自定义POJO类型字段递归处理
  • 增加类型判断边界,基础类型、包装类型、枚举等无需递归的类型直接跳过

代码实现

import java.lang.reflect.Field;
import java.util.IdentityHashMap;
import java.util.Set;

// 过滤逻辑抽为函数式接口方便扩展
@FunctionalInterface
interface StringFilter {
    String apply(String origin);
}

public class AnnotatedPropProcessor {
    public static void processPojo(Object obj, StringFilter filter) {
        // 基于对象引用判断已访问对象,避免值相同的不同对象被误判
        Set<Object> visited = Set.newInstanceFrom(new IdentityHashMap<>());
        doProcess(obj, filter, visited);
    }

    private static void doProcess(Object obj, StringFilter filter, Set<Object> visited) {
        if (obj == null || visited.contains(obj)) {
            return;
        }
        visited.add(obj);

        // 遍历当前类所有声明字段,包括private修饰的字段
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                // 处理带@AnnotatedProp注解的String类型字段
                if (field.getType() == String.class && field.isAnnotationPresent(AnnotatedProp.class)) {
                    String originValue = (String) field.get(obj);
                    if (originValue != null) {
                        String newValue = filter.apply(originValue);
                        field.set(obj, newValue);
                    }
                    continue;
                }

                // 跳过无需递归的类型:基础类型、枚举、数组、JDK自带类型(String、集合、包装类等)
                Class<?> fieldType = field.getType();
                if (fieldType.isPrimitive() 
                    || fieldType.isEnum() 
                    || fieldType.isArray()
                    || fieldType.getName().startsWith("java.")
                    ) {
                    continue;
                }

                // 递归处理自定义POJO类型字段
                Object fieldValue = field.get(obj);
                doProcess(fieldValue, filter, visited);

                // 如需处理List<SubPojo>这类集合类型的嵌套POJO,可放开下面的扩展逻辑
                /*
                if (fieldValue instanceof Iterable<?> iterable) {
                    for (Object item : iterable) {
                        doProcess(item, filter, visited);
                    }
                }
                */

            } catch (IllegalAccessException e) {
                // 按需调整异常处理逻辑
                throw new RuntimeException("字段处理失败", e);
            }
        }
    }
}

使用示例

// 示例过滤逻辑:把字段值中的"敏感词"替换为*
Pojo pojo = new Pojo();
// 给pojo属性赋值逻辑...
AnnotatedPropProcessor.processPojo(pojo, originStr -> originStr.replace("敏感词", "*"));

可选优化点

  • 可对类的字段信息做本地缓存,避免每次处理对象都重新反射获取字段,大幅提升批量处理的性能
  • 可按需扩展对Map、数组等其他容器类型的处理逻辑

内容的提问来源于stack exchange,提问作者Alexander Widera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 21:45:02