You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java如何获取对象的所有非空嵌套属性?

实现Java对象的扁平化非空属性列表获取

现有Java类

class Car{
    String carName;
    String serial;
    Wheel wheel;
}
class Wheel{
    String wheelName;
    Integer someInt1;
    Integer someInt2; 
    Set<Integer> someSet;
}

对象实例

Wheel w = new Wheel("wheehee", null, 3,  null); 
Car c = new Car("car", "123", w);

需求说明

需要获取对象c的扁平化非空属性列表,最终应包含以下属性:

  • "carName"
  • "serial"
  • "wheel"
  • "wheelName"
  • "someInt2"

已知通过反射API可以实现非空属性检查,但无法处理嵌套属性,特此寻求解决方案。

解决方案

可以通过递归反射的方式实现,遍历对象所有属性,判断属性值是否非空:若为基础类型、包装类或字符串等直接判断;若为自定义对象,则递归处理其内部属性,同时收集非空的属性名(包括嵌套对象本身)。

以下是具体实现代码:

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class NonNullPropertyCollector {

    public static List<String> collectNonNullProperties(Object obj) throws IllegalAccessException {
        List<String> result = new ArrayList<>();
        if (obj == null) {
            return result;
        }
        Class<?> clazz = obj.getClass();
        // 获取类的所有声明字段(包含私有字段)
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            Object value = field.get(obj);
            String fieldName = field.getName();
            // 当前属性非空则加入结果列表
            if (value != null) {
                result.add(fieldName);
                // 如果是自定义对象,递归收集其非空属性
                if (isCustomObject(value)) {
                    result.addAll(collectNonNullProperties(value));
                }
            }
        }
        return result;
    }

    // 判断是否为需要递归处理的自定义对象
    private static boolean isCustomObject(Object value) {
        Class<?> clazz = value.getClass();
        return !clazz.isPrimitive()
                && !isWrapperType(clazz)
                && !String.class.equals(clazz)
                && !Set.class.isAssignableFrom(clazz)
                && !clazz.isArray();
    }

    // 判断是否为包装类型
    private static boolean isWrapperType(Class<?> clazz) {
        return clazz == Integer.class || clazz == Long.class || clazz == Double.class
                || clazz == Float.class || clazz == Boolean.class || clazz == Character.class
                || clazz == Byte.class || clazz == Short.class;
    }

    // 测试方法
    public static void main(String[] args) throws IllegalAccessException {
        Wheel w = new Wheel("wheehee", null, 3, null);
        Car c = new Car("car", "123", w);
        List<String> nonNullProps = collectNonNullProperties(c);
        nonNullProps.forEach(System.out::println);
        // 输出结果:carName、serial、wheel、wheelName、someInt2
    }
}

代码说明

  1. 递归遍历逻辑:通过反射获取对象的所有字段,对每个非空字段进行记录,若字段值为自定义对象则递归处理其内部属性。
  2. 类型过滤:通过isCustomObject方法排除基础类型、包装类、字符串、集合等无需递归的类型,避免无效处理。
  3. 私有字段访问:调用field.setAccessible(true)确保能读取类的私有字段。

内容的提问来源于stack exchange,提问作者S.Dan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:02:39