为什么我得到StackOverflowError

时间:2010-08-29 07:18:00

标签: java stack-overflow

public class Category {

    private Category parentCategory;
    private Set<Category> childCategories;
    private String name;

    public Category() {
        childCategories = new HashSet<Category>();
    }

    public Category getParentCategory() {
        return parentCategory;
    }

    public void setParentCategory(Category parentCategory) {
        this.parentCategory = parentCategory;
    }

    public Set<Category> getChildCategories() {
        return childCategories;
    }

    public void setChildCategories(Set<Category> childCategories) {
        this.childCategories = childCategories;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Category [childCategories=" + childCategories + ", name="
                + name + ", parentCategory=" + parentCategory + "]";
    }

}


public static void main(String[] args) {
        Category books = new Category();
        books.setName("Books");
        books.setParentCategory(null);

        Category novels = new Category();
        novels.setName("Novels");
        novels.setParentCategory(books);

        books.getChildCategories().add(novels);
        //novels.setChildCategories(null);

        System.out.println("Books > " + books);
    }

System.out.println正在生成StackOverflowError

6 个答案:

答案 0 :(得分:16)

当您执行toString()时,请致电孩子的toString()。这里没问题,除了你在这里调用父项的toString()。这将调用孩子的toString()等。

好的无限循环。

摆脱它的最佳方法是将toString()方法更改为:

@Override
public String toString() {
    return "Category [childCategories=" + childCategories + ", name="
            + name + ", parentCategory=" + parentCategory.getName() + "]";
}

这样你就不会打印parentCategory而只打印它的名字,没有无限循环,没有StackOverflowError。

编辑:正如Bolo所说,您需要检查parentCategory是否为空,如果是,则可能有NullPointerException


资源:

关于同一主题:

答案 1 :(得分:2)

由于错误是System.out.println,问题必须在toString()

问题在于,toString()会使用Category方法为您打印的父对象和子toString()对象打印。因此,当您打印一个类别时,它会在父母上调用toString(),该父母会在孩子上调用toString(),该父母会在孩子上调用toString(),并在孩子身上调用toString(),依此类推,直到堆栈已经用尽。

答案 2 :(得分:2)

你的toString()正在进行递归的旋转。你需要有两个toString();一个用于父母,一个用于孩子。您的toString可能如下所示:

@Override
public String toString() {
     toStringParent(parent);   // This print only parent
     toStringChildren(children);  // This print only children
}

答案 3 :(得分:1)

因为每次拨打Category#toString()都会产生大量其他toString s。请注意,打印childCategories会导致打印出每个元素(通过toString),这反过来会重复许多toString方法调用的整个过程。

不仅如此,而且每个孩子都会在其父级上调用toString,而父级又会在其子级上调用toString,每个子级在父级上调用toString,而父级又调用toString关于其子女的{1}} ......

答案 4 :(得分:1)

return "Category [childCategories=" + childCategories + ", name="
                + name + ", parentCategory=" + parentCategory + "]";

您正在使用parentCategory之类的实例连接到您的toString。它会调用这些实例的toString方法。

这个toString调用循环永远不会结束。因为子类别将调用父类别,父类将再次调用子类,所以......

如果您放置:System.out.println(myObject);它实际上是:System.out.println(myObject.toString());

答案 5 :(得分:1)

实际上在构建将传递给StackOverflowError的{​​{1}}参数时引发了{p> String

每次连接System.out.printlnString时,都会执行Category toString()方法。问题是Category中的toString()有点过于冗长。修复它的一种方法是只打印父类别的名称(跳过它的父级和子级):

Category