5

我注意到,如果我执行以下操作:

ArrayList anArray = new ArrayList();
anArray.add(anArray);

Netbeans 自动编译器似乎没有任何问题,我似乎仍然能够引用所有内容。这样做有什么不好的副作用吗?

4

4 回答 4

7

我怀疑在大多数情况下会发生任何不好的事情。

如果您以递归方式处理列表,则会出现问题,在这种情况下,您最终会出现堆栈溢出。

于 2013-06-20T18:13:59.010 回答
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;
    }

}
于 2013-06-20T18:13:47.883 回答
3

是的。这是一个不良副作用的具体例子。

在 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 中,那么您的程序将失败。

所以是的,向自身添加列表会产生不良的副作用。

于 2015-05-31T15:07:27.210 回答
2

,这本身并没有错。

(但是,正如所指出的,如果您对该对象执行递归操作,您可能会陷入无限循环。)

于 2013-06-20T18:14:07.617 回答