为什么我得到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.println
的String
参数时引发StackOverflowError
。
每次连接String
和Category
,都会执行Category
的toString()
方法。 问题是你的Category
中的toString()
有点过于冗长。 修复它的一种方法是只打印父类别的名称(跳过它的父级和子级):
@Override public String toString() { return "Category [childCategories=" + childCategories + ", name=" + name + ", parentCategory=" + ((parentCategory == null) ? null : parentCategory.getName()) + "]"; }