mar*_*hon 16 java recursion tostring
如果收集项的图形中的某个地方是一个返回自身的引用,则对集合上的字符串可以进入无限循环.见下面的例子.
是的,良好的编码实践应该首先防止这种情况,但无论如何,我的问题是:在这种情况下检测递归的最有效方法是什么?
一种方法是在threadlocal中使用一个集合,但这看起来有点沉重.
public class AntiRecusionList<E> extends ArrayList<E> {
@Override
public String toString() {
if ( /* ???? test if "this" has been seen before */ ) {
return "{skipping recursion}";
} else {
return super.toString();
}
}
}
public class AntiRecusionListTest {
@Test
public void testToString() throws Exception {
AntiRecusionList<AntiRecusionList> list1 = new AntiRecusionList<>();
AntiRecusionList<AntiRecusionList> list2 = new AntiRecusionList<>();
list2.add(list1);
list1.add(list2);
list1.toString(); //BOOM !
}
}
Run Code Online (Sandbox Code Playgroud)
Den*_*ret 11
当我必须迭代风险图时,我通常使用递减计数器来创建函数.
例如 :
public String toString(int dec) {
if ( dec<=0 ) {
return "{skipping recursion}";
} else {
return super.toString(dec-1);
}
}
public String toString() {
return toString(100);
}
Run Code Online (Sandbox Code Playgroud)
我不会坚持,正如你已经知道的那样,但这并不尊重合同toString()
必须简短和可预测的.
我在问题中提到的 threadlocal 位:
public class AntiRecusionList<E> extends ArrayList<E> {
private final ThreadLocal<IdentityHashMap<AntiRecusionList<E>, ?>> fToStringChecker =
new ThreadLocal<IdentityHashMap<AntiRecusionList<E>, ?>>() {
@Override
protected IdentityHashMap<AntiRecusionList<E>, ?> initialValue() {
return new IdentityHashMap<>();
}
};
@Override
public String toString() {
boolean entry = fToStringChecker.get().size() == 0;
try {
if (fToStringChecker.get().containsKey(this)/* test if "this" has been seen before */) {
return "{skipping recursion}";
} else {
fToStringChecker.get().put(this, null);
entry = true;
}
return super.toString();
} finally {
if (entry)
fToStringChecker.get().clear();
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8756 次 |
最近记录: |