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

Java获取对象及内部对象变量名、自定义列表类名与对象的实现方法

看来你需要的是一套能深度遍历对象结构的反射工具——不仅要获取当前对象的表层字段,还要能钻取嵌套对象、解析集合里的元素信息,这在做调试、日志打印或者对象序列化工具时特别实用。下面针对你的需求给出完整解决方案:

解决方案:深度递归的对象信息获取工具

首先得指出你原有代码的两个核心局限:

  • 只能获取公共(public)字段,私有/保护字段会被忽略
  • 没有处理嵌套对象和集合类型,无法深度遍历对象结构

我们可以通过递归反射+类型分支处理来实现任意对象的全量信息获取,下面是具体实现:

核心实现思路

  1. 递归遍历对象的所有字段(包括私有字段)
  2. 根据字段值的类型做分支处理:
    • 基本类型/包装类/字符串:直接输出字段名、类型和值
    • 嵌套对象:递归调用获取其内部所有字段信息
    • 集合/数组:遍历每个元素,输出元素的类名和详细信息
  3. 加入循环引用防护,避免无限递归

完整代码实现

import java.lang.reflect.Field;
import java.lang.reflect.Array;
import java.util.*;

public class ObjectInspector {

    // 记录已处理的对象,防止循环引用导致无限递归
    private static final Set<Object> processedObjects = new HashSet<>();

    public static void inspectObject(Object obj) {
        if (obj == null || processedObjects.contains(obj)) {
            System.out.println(obj);
            return;
        }
        processedObjects.add(obj);
        Class<?> clazz = obj.getClass();
        System.out.printf("=== 类名: %s ===%n", clazz.getSimpleName());

        // 获取类的所有字段(包括私有、保护字段)
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true); // 突破访问限制,允许访问私有字段
            try {
                Object fieldValue = field.get(obj);
                System.out.printf("字段名: %s, 类型: %s, 值: ", 
                    field.getName(), field.getType().getSimpleName());
                
                // 根据字段值类型分情况处理
                if (isBasicType(fieldValue)) {
                    System.out.println(fieldValue);
                } else if (fieldValue instanceof Collection) {
                    inspectCollection((Collection<?>) fieldValue);
                } else if (fieldValue.getClass().isArray()) {
                    inspectArray(fieldValue);
                } else {
                    // 嵌套对象,递归处理其内部结构
                    System.out.println();
                    inspectObject(fieldValue);
                }
            } catch (IllegalAccessException e) {
                System.out.println("无法访问字段: " + e.getMessage());
            }
        }
        processedObjects.remove(obj); // 处理完当前对象后移除,不影响其他分支遍历
    }

    // 判断是否为基本类型、包装类或字符串
    private static boolean isBasicType(Object obj) {
        if (obj == null) return true;
        Class<?> clazz = obj.getClass();
        return clazz.isPrimitive() 
            || clazz.equals(String.class)
            || clazz.equals(Integer.class) || clazz.equals(Long.class)
            || clazz.equals(Double.class) || clazz.equals(Float.class)
            || clazz.equals(Boolean.class) || clazz.equals(Character.class)
            || clazz.equals(Byte.class) || clazz.equals(Short.class);
    }

    // 处理集合类型(List/Set等)
    private static void inspectCollection(Collection<?> collection) {
        System.out.printf("集合类型: %s, 元素数量: %d%n", 
            collection.getClass().getSimpleName(), collection.size());
        int index = 0;
        for (Object element : collection) {
            System.out.printf("  元素[%d] - 类名: %s, 值: ", 
                index, element != null ? element.getClass().getSimpleName() : "null");
            if (isBasicType(element)) {
                System.out.println(element);
            } else {
                System.out.println();
                inspectObject(element);
            }
            index++;
        }
    }

    // 处理数组类型
    private static void inspectArray(Object array) {
        int length = Array.getLength(array);
        System.out.printf("数组类型: %s, 长度: %d%n", 
            array.getClass().getComponentType().getSimpleName(), length);
        for (int i = 0; i < length; i++) {
            Object element = Array.get(array, i);
            System.out.printf("  元素[%d] - 类名: %s, 值: ", 
                i, element != null ? element.getClass().getSimpleName() : "null");
            if (isBasicType(element)) {
                System.out.println(element);
            } else {
                System.out.println();
                inspectObject(element);
            }
        }
    }

    // 测试用例(对应你给出的A、B类)
    static class A {
        String a = "nil";
        B b = new B();
        List<B> bList = Arrays.asList(new B(), new B());
    }

    static class B {
        int n1 = 0;
        String n2 = "testB";
    }

    public static void main(String[] args) {
        inspectObject(new A());
    }
}

关键功能说明

  1. 获取嵌套对象详情:比如你的A类里的b对象,代码会自动递归调用inspectObject,输出B类的所有字段(包括私有字段)
  2. 获取自定义列表信息:inspectCollection方法会输出集合的类名(比如ArrayList)、元素数量,还会逐个遍历元素,输出每个元素的类名和详细信息
  3. 兼容多种类型:支持基本类型、包装类、字符串、集合、数组、嵌套对象的全量遍历
  4. 防循环引用:用processedObjects集合记录已处理的对象,避免对象互相引用导致的无限递归

测试输出示例

运行main方法后,会输出类似以下的结构化结果:

=== 类名: A ===
字段名: a, 类型: String, 值: nil
字段名: b, 类型: B, 值: 
=== 类名: B ===
字段名: n1, 类型: int, 值: 0
字段名: n2, 类型: String, 值: testB
字段名: bList, 类型: List, 值: 集合类型: ArrayList, 元素数量: 2
  元素[0] - 类名: B, 值: 
=== 类名: B ===
字段名: n1, 类型: int, 值: 0
字段名: n2, 类型: String, 值: testB
  元素[1] - 类名: B, 值: 
=== 类名: B ===
字段名: n1, 类型: int, 值: 0
字段名: n2, 类型: String, 值: testB

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:40:29