我在执行下面的代码时获得java.lang.StackOverflowError
,
public class Insertion {
private static ArrayList integers1 = new ArrayList();
private static ArrayList integers2 = new ArrayList();
public static void main(String[] args) {
Collections.addAll(integers1, 1, 2, 3);
Collections.addAll(integers2, 5, 6, 7);
integers1.add(integers2);
System.out.println(integers1);
integers2.add(integers1);
System.out.println(integers2);
}
}
请解释原因?
答案 0 :(得分:12)
当您尝试打印列表时,会发生StackOverflow。
您有两个列表:integers1=[1,2,3,integers2]
和integers2=[5,6,7,integers1]
当您尝试打印integers2
时,实际上是打印:
[1,2,3,integers1.toString()]
和integers1.toString()
是[5,6,7,integers2.toString()]
,后者又一次又一次调用integers1.toString()
。这导致无限循环,仅在堆栈溢出时结束。
此打印的理论结果为[1,2,3,5,6,7,1,2,3,5,6,7,... (infinite repeat)]
,这是通过递归完成的 - 但在某些时候,堆栈已满并且程序中断。
答案 1 :(得分:7)
在这一行:
integers1.add(integers2);
您要将整个数组列表添加到另一个数组列表中。当你这样做时:
integers2.add(integers1);
您创建循环引用。繁荣 - 当您尝试打印时会发生异常。
如果您使用过泛型,那就不会发生这种情况。我假设你只想在你的列表中保留整数,因此这个声明会导致你的代码无法编译:
private static ArrayList<Integer> integers1 = new ArrayList<>();
private static ArrayList<Integer> integers2 = new ArrayList<>();
// ...
// The method add(Integer) in the type ArrayList<Integer> is not applicable
// for the arguments (ArrayList<Integer>)
integers1.add(integers2);
答案 2 :(得分:4)
您已经对无限循环和StackOverflow进行了很好的解释。
现在,假设这个循环引用不是你的意图,你可能想要将一个列表的元素添加到另一个列表中。这是通过addAll
:
integers1.addAll(integers2);
integers2.addAll(integers1);