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 } }
代码说明
- 递归遍历逻辑:通过反射获取对象的所有字段,对每个非空字段进行记录,若字段值为自定义对象则递归处理其内部属性。
- 类型过滤:通过
isCustomObject方法排除基础类型、包装类、字符串、集合等无需递归的类型,避免无效处理。 - 私有字段访问:调用
field.setAccessible(true)确保能读取类的私有字段。
内容的提问来源于stack exchange,提问作者S.Dan
相关产品推荐
相关产品推荐

