构造函数中的 StackOverflowError 异常

StackOverflowError exception in constructor

我收到了这个异常。

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

这是否意味着 class 不能将其自身的对象作为变量包含?但是在链表实现中,节点可以包含指向自身的节点?[​​=12=]

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);
    }
}
}

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

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

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 WhosebugError?
}

不要认为它与包含自身对象作为变量的 class 有任何关系。

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

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);
    }
  }
}

这个怎么样:

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);
    }
}
}