构造函数中的StackOverflowError异常

时间:2015-05-26 02:18:36

标签: java constructor

我收到了这个例外。

Exception in thread "main" java.lang.StackOverflowError
at java.util.AbstractCollection.<init>(AbstractCollection.java:66)
at java.util.AbstractList.<init>(AbstractList.java:76)
at java.util.ArrayList.<init>(ArrayList.java:151)

这是否意味着一个类不能将自身的对象包含为变量?但是在链表实现中,节点可以包含指向自身的节点吗?

public class Test {

String name;
List<Test> related;

public Test() {

    name = "dog";
    related = new ArrayList<Test>();    
    related.add(new Test());
    related.add(new Test());
    related.add(new Test());
}

public List<Test> relate() {

    return related;
}

public String toString() {
    return name;
}

public static void main(String[] args) {

    Test test = new Test();
    for(Test t : test.relate()) {
        System.out.println(t);
    }
}
}

4 个答案:

答案 0 :(得分:2)

您的构造函数创建了三个自身的新实例,每个实例创建三个新实例,每个实例创建三个新实例,依此类推。

要修复它,您应该创建两个单独的类 - 一个用于实现链接列表,另一个用于创建和使用链接列表。

答案 1 :(得分:1)

public Test() {

    name = "dog";
    related = new ArrayList<Test>();    
    related.add(new Test()); // Here, you can calling the constructor
    related.add(new Test()); // recursively within the constructor?
    related.add(new Test()); // Hence the StackOverflowError?
}

不要认为它与包含自身对象的类有任何关系。

答案 2 :(得分:1)

您可以通过向构造函数添加一个参数来解决问题,该参数指定要添加的元素数量,证明问题是代码中的无限递归,而不是在构造函数中创建新实例的固有问题:

import java.util.ArrayList;
import java.util.List;

public class Test {

  String name;
  List<Test> related;

  public Test(int numberToAdd) {

    name = "dog";
    related = new ArrayList<Test>();
    for (int i = 0; i < numberToAdd; i++) {
      related.add(new Test(0));
    }
  }

  public List<Test> relate() {

    return related;
  }

  public String toString() {
    return name;
  }

  public static void main(String[] args) {

    Test test = new Test(3);
    for (Test t : test.relate()) {
      System.out.println(t);
    }
  }
}

答案 3 :(得分:0)

这个怎么样:

package com.my.test;

import java.util.ArrayList;
import java.util.List;

public class Test {

private String name;
private List<Test> related;

public Test(String name, int times) {
    this.name = name;
    related = new ArrayList<Test>();
    for(int i = 0; i < times; i++) {
        related.add(new Test("child"+i, 0));
    }
}

public List<Test> relate() {
    return related;
}

public String toString() {
    return name;
}

public static void main(String[] args) {
    Test test = new Test("parent", 3);
    for (Test t : test.relate()) {
        System.out.println(t);
    }
}
}