gpt4 book ai didi

java - 尝试用反射检测Java中的循环引用

转载 作者:行者123 更新时间:2023-11-30 08:10:37 26 4
gpt4 key购买 nike

我继承了一些遗留代码,如果存在循环引用,这些代码就会失败。该代码采用一个对象并构建整个对象图以转换为 XML。遗留代码无法修改,因此我想检测引用并进行相应处理。

现在,我正在构建图表中每个对象上的所有字段的集合,然后运行每个对象字段并尝试检测对象是否相等。

这是构建 Set 的遗留代码部分。

// declaration of set for this instance
Set<Object> noduplicates = new HashSet<Object>();


private Iterator<Field> findAllFields(Object o) {
Collection<Field> result = new LinkedList<Field>();j
Class<? extends Object> c = o.getClass();
while (c != null) {
Field[] f = c.getDeclaredFields();
for (int i = 0; i < f.length; i++) {
if (!Modifier.isStatic(f[i].getModifiers())) {
result.add(f[i]);
}
}
c = c.getSuperclass();
}
// add the fields for each object, for later comparison
noduplicates.addAll((Collection<?>) result);
testForDuplicates(noduplicates)
}

这是当前检测循环的尝试(灵感来自:https://stackoverflow.com/a/2638662/817216):

private void testForDuplicates(Set<Object> noduplicates) throws ... {
for (Object object : noduplicates) {
Field[] fields = object.getClass().getFields();
for (Field field : fields) {
for (PropertyDescriptor pd : Introspector.getBeanInfo(field.getClass()).getPropertyDescriptors()) {
if (pd.getReadMethod() != null && !"class".equals(pd.getName())) {
Object possibleDuplicate = pd.getReadMethod().possibleDuplicate(object);
if (object.hashCode() == possibleDuplicate.hashCode()) {
System.out.println("Duplicated detected");
throw new RuntimeException();
}

}
}

}
}
}

我有一个非常简单的测试用例,两个 POJO,每个 POJO 都互相引用:

class Prop {
private Loc loc;

public Loc getLoc() {
return loc;
}

public void setLoc(Loc loc) {
this.loc = loc;
}
}

class Loc {
private Prop prop;

public Prop getProp() {
return prop;
}

public void setProp(Prop prop) {
this.prop = prop;
}
}

我尝试了上述方法的几种变体,包括直接测试对象相等性。目前对哈希码相等性的测试从未检测到循环性。

非常感谢您的指点。

最佳答案

最后我自己想出了这个办法。我在使用 Reflection API 时遇到的部分困惑是,例如,当您调用 Field.get(object);

object 必须是包含该字段的类的实例,这是有道理的,但并不立即直观(至少对我来说不是)。

文档指出:

get(Object obj)
Returns the value of the field represented by this Field, on the specified object.

最后,我提出的解决方案依赖于存储每个对象的类类型的 Map,并使用它来确定其任何字段是否引用它。

这就是我最终得到的结果:

 boolean testForDuplicates(Set<Object> noduplicates2) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, IntrospectionException {
Map<Object, Object> duplicatesMap = new HashMap<Object, Object>();
for (Object object : noduplicates2) {
duplicatesMap.put(object.getClass(), object);
}

for (Object object : noduplicates2) {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
if (duplicatesMap.containsKey(field.getType())) {
Object possibleDupeFromField = duplicatesMap.get(field.getType());
if (noduplicates2.contains(possibleDupeFromField)) {
return true;
}
}
}
}
return false;
}

我将在有问题的真实代码中对其进行测试,如果发现任何其他内容,请进行更新。

关于java - 尝试用反射检测Java中的循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30434820/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com