我正在使用JDI重新编码方法中的变量状态。根据教程,我找不到如何获取objectReference值,例如List,Map或我的自定义类。它只能获取PrimtiveValue。

StackFrame stackFrame = ((BreakpointEvent) event).thread().frame(0);
 Map<LocalVariable, Value> visibleVariables = (Map<LocalVariable, Value>) stackFrame
                            .getValues(stackFrame.visibleVariables());
                        for (Map.Entry<LocalVariable, Value> entry : visibleVariables.entrySet()) {
                            System.out.println("console->>" + entry.getKey().name() + " = " + entry.getValue());
                        }
}


如果LocalVariable是PrimtiveValue类型,例如int a = 10;,则它将打印

console->> a = 10


如果LocalVariable是ObjectReference类型,例如Map data = new HashMap();data.pull("a",10),则它将打印

console->> data = instance of java.util.HashMap(id=101)


但我想得到如下结果

console->> data = {a:10} // as long as get the data of reference value


谢谢!

最佳答案

ObjectReference没有“值”。它本身是Value的实例。

您可能想要的是获取此ObjectReference引用的对象的字符串表示形式。在这种情况下,您需要在该对象上调用toString()方法。

调用ObjectReference.invokeMethod,将Method传递给toString()。结果,您将获得一个StringReference实例,然后在该实例上调用value()以获取所需的字符串表示形式。

for (Map.Entry<LocalVariable, Value> entry : visibleVariables.entrySet()) {
    String name = entry.getKey().name();
    Value value = entry.getValue();

    if (value instanceof ObjectReference) {
        ObjectReference ref = (ObjectReference) value;
        Method toString = ref.referenceType()
                .methodsByName("toString", "()Ljava/lang/String;").get(0);
        try {
            value = ref.invokeMethod(thread, toString, Collections.emptyList(), 0);
        } catch (Exception e) {
            // Handle error
        }
    }

    System.out.println(name + " : " + value);
}

08-07 11:36