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

如何使用Jackson对JDI的Value对象进行内容查看与格式化JSON输出

问题原因

你直接用Jackson序列化JDI的Value对象无法获取业务数据,Value只是JDI提供的远端目标JVM对象的本地代理类,本身仅存储了远端对象的引用状态、是否被回收等元信息,你看到的collected字段就是代理类自带的属性,和远端真实对象的业务字段无关。

解决方案

不需要手动编写全量递归判断逻辑,给Jackson注册对应Value各子类型的自定义序列化器即可,步骤如下:

  1. 编写Value类型的通用序列化器,自动处理类型分发和递归序列化
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.sun.jdi.*;
import java.io.IOException;

public class JdiValueSerializer extends StdSerializer<Value> {
    public JdiValueSerializer() {
        super(Value.class);
    }

    @Override
    public void serialize(Value value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }
        // 按实际子类型分发处理
        if (value instanceof StringReference) {
            gen.writeString(((StringReference) value).value());
        } else if (value instanceof PrimitiveValue) {
            // 处理基本类型/包装类型
            if (value instanceof BooleanValue) {
                gen.writeBoolean(((BooleanValue) value).value());
            } else if (value instanceof ByteValue) {
                gen.writeNumber(((ByteValue) value).value());
            } else if (value instanceof CharValue) {
                gen.writeString(String.valueOf(((CharValue) value).value()));
            } else if (value instanceof ShortValue) {
                gen.writeNumber(((ShortValue) value).value());
            } else if (value instanceof IntValue) {
                gen.writeNumber(((IntValue) value).value());
            } else if (value instanceof LongValue) {
                gen.writeNumber(((LongValue) value).value());
            } else if (value instanceof FloatValue) {
                gen.writeNumber(((FloatValue) value).value());
            } else if (value instanceof DoubleValue) {
                gen.writeNumber(((DoubleValue) value).value());
            }
        } else if (value instanceof ArrayReference) {
            ArrayReference arr = (ArrayReference) value;
            gen.writeStartArray();
            for (Value item : arr.getValues()) {
                provider.defaultSerializeValue(item, gen);
            }
            gen.writeEndArray();
        } else if (value instanceof ObjectReference) {
            ObjectReference obj = (ObjectReference) value;
            if (obj.isCollected()) {
                gen.writeString("[已回收对象]");
                return;
            }
            gen.writeStartObject();
            // 遍历对象所有字段,可自行加规则过滤静态/常量等字段
            for (Field field : obj.referenceType().allFields()) {
                // 示例:过滤静态字段
                // if(field.isStatic()) continue;
                Value fieldValue = obj.getValue(field);
                gen.writeFieldName(field.name());
                provider.defaultSerializeValue(fieldValue, gen);
            }
            gen.writeEndObject();
        } else if (value instanceof VoidValue) {
            gen.writeNull();
        } else {
            // 兜底逻辑,避免未知类型导致序列化失败
            gen.writeString(value.type().name());
        }
    }
}
  1. 初始化复用ObjectMapper并注册序列化器,不要在循环中重复创建ObjectMapper
// 全局初始化一次即可
ObjectMapper mapper = new ObjectMapper();
SimpleModule jdiModule = new SimpleModule("JdiValueSerializeModule");
jdiModule.addSerializer(Value.class, new JdiValueSerializer());
// 可选配置:格式化输出JSON
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(jdiModule);

// 断点事件处理逻辑
StackFrame sf = event.thread().frame(0);
for (Value v : sf.getArgumentValues()) {
    try {
        System.out.println(mapper.writeValueAsString(v));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

可选优化

如果有特殊类型需要定制序列化逻辑,只需要新增对应子类型的序列化器注册到模块中即可,不需要修改原有业务代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:51:03