我注意到,如果我做了类似的事情:
ArrayList anArray = new ArrayList();
anArray.add(anArray);
Netbeans自动编译器似乎没有任何问题,我似乎仍然能够引用所有内容。这样做有什么不好的副作用吗?
答案 0 :(得分:7)
我怀疑在大多数情况下会发生什么坏事。
如果你以递归方式处理列表会出现问题,在这种情况下你最终会出现堆栈溢出。
答案 1 :(得分:5)
当您打印出来时,它会产生非常有趣的效果:
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;
}
}
答案 2 :(得分:2)
否,这没有任何内在错误。
(但是,正如所指出的,如果对该对象进行递归操作,最终可能会进入无限循环。)
答案 3 :(得分:2)
是。这是一个不良副作用的具体例子。
在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中,那么您的程序将失败。
所以是的,向自己添加列表会产生不良副作用。