我注意到,如果我执行以下操作:
ArrayList anArray = new ArrayList();
anArray.add(anArray);
Netbeans 自动编译器似乎没有任何问题,我似乎仍然能够引用所有内容。这样做有什么不好的副作用吗?
我注意到,如果我执行以下操作:
ArrayList anArray = new ArrayList();
anArray.add(anArray);
Netbeans 自动编译器似乎没有任何问题,我似乎仍然能够引用所有内容。这样做有什么不好的副作用吗?
我怀疑在大多数情况下会发生任何不好的事情。
如果您以递归方式处理列表,则会出现问题,在这种情况下,您最终会出现堆栈溢出。
当你打印出来时,它会产生一个非常有趣的效果:
package com.sandbox;
import java.util.ArrayList;
public class Sandbox {
public static void main(String[] args) {
ArrayList anArray = new ArrayList();
anArray.add(anArray);
for (Object o : anArray) {
System.out.println(o);
}
}
}
这打印出来:
[(本集)]
除此之外,我还没有想出一种方法来破坏这样的程序。我不认为这有什么问题。
正如@wobblycogs 提到的,在列表上使用递归时必须小心,但考虑到这并不是一个特殊情况。这只是一个循环依赖,类似于这段代码给出的stackoverflow:
package com.sandbox;
public class Sandbox {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.b = b;
b.a = a;
traverse(a);
}
private static void traverse(A a) {
traverse(a.b);
}
private static void traverse(B b) {
traverse(b.a);
}
private static class A {
private B b;
}
private static class B {
private A a;
}
}
是的。这是一个不良副作用的具体例子。
在 ArrayList 中,hashCode
实现如下。
public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
因此,如果一个列表包含自身,并且您hashCode()
在该列表上调用,您将获得 StackOverflow 异常。
在现实世界的用例中,如果您将此 List 放在 Map 中,那么您的程序将失败。
所以是的,向自身添加列表会产生不良的副作用。
不,这本身并没有错。
(但是,正如所指出的,如果您对该对象执行递归操作,您可能会陷入无限循环。)