为什么我得到StackOverflowError

public class Category { private Category parentCategory; private Set childCategories; private String name; public Category() { childCategories = new HashSet(); } public Category getParentCategory() { return parentCategory; } public void setParentCategory(Category parentCategory) { this.parentCategory = parentCategory; } public Set getChildCategories() { return childCategories; } public void setChildCategories(Set 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

当你执行toString() ,你可以调用子toString() 。 这里没问题,除了你在这里调用父类的toString() 。 这会调用孩子的toString()等。

好的无限循环。

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

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

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

编辑:正如Bolo所说,你需要检查parentCategory是否为null,如果是,你可能会有NullPointerException


资源:

  • Javadoc – StackOverflowError

在同一主题上:

  • java中的toString()
  • Java后缀计算器中的StackOverFlowError

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

问题是toString()使用他们的toString()方法打印您的打印的父对象和子Category对象。 因此,当你打印一个Category时,它会调用父类上的toString() ,该父类调用子节点上的toString() ,调用父节点上的toString() ,调用子节点上的toString() ,依此类推,直到堆栈耗尽为止。

你的toString()进入递归的tailspin。 你需要有两个toString() ; 一个用于父母,一个用于孩子。 你的toString看起来像这样:

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

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

不仅如此,每个子toString调用其父toString上的toString ,进而调用其子toString上的toString ,每个子toString调用父toString上的toString ,后者又调用其子toString上的toString ,…

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

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

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

如果你把它放在: System.out.println(myObject); 它实际上是: System.out.println(myObject.toString());

实际上,在构建将传递给System.out.printlnString参数时引发StackOverflowError

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

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