Java 为什么我';I’我要越狱了 公共类类别{ 私人类; 私设儿童类别; 私有字符串名称; 公共类别(){ childCategories=新HashSet(); } 公共类别getParentCategory(){ 返回父类别; } 公共无效setParentCategory(类别parentCategory){ this.parentCategory=parentCategory; } 公共集getChildCategories(){ 返回子类别; } 公共无效setChildCategories(设置childCategories){ this.childCategories=childCategories; } 公共字符串getName(){ 返回名称; } 公共void集合名(字符串名){ this.name=名称; } @凌驾 公共字符串toString(){ return“Category[childCategories=“+childCategories+”,name=” +name+”,parentCategory=“+parentCategory+”]; } } 公共静态void main(字符串[]args){ 类别书籍=新类别(); books.setName(“books”); books.setParentCategory(空); 类别小说=新类别(); 小说集名(“小说”); 小说类(书籍); books.getChildCategories().add(小说); //小说。设置儿童类别(空); System.out.println(“Books>”+Books); }
Java 为什么我';I’我要越狱了 公共类类别{ 私人类; 私设儿童类别; 私有字符串名称; 公共类别(){ childCategories=新HashSet(); } 公共类别getParentCategory(){ 返回父类别; } 公共无效setParentCategory(类别parentCategory){ this.parentCategory=parentCategory; } 公共集getChildCategories(){ 返回子类别; } 公共无效setChildCategories(设置childCategories){ this.childCategories=childCategories; } 公共字符串getName(){ 返回名称; } 公共void集合名(字符串名){ this.name=名称; } @凌驾 公共字符串toString(){ return“Category[childCategories=“+childCategories+”,name=” +name+”,parentCategory=“+parentCategory+”]; } } 公共静态void main(字符串[]args){ 类别书籍=新类别(); books.setName(“books”); books.setParentCategory(空); 类别小说=新类别(); 小说集名(“小说”); 小说类(书籍); books.getChildCategories().add(小说); //小说。设置儿童类别(空); System.out.println(“Books>”+Books); },java,stack-overflow,Java,Stack Overflow,System.out.println正在生成stackOverflowerError当您执行toString()时,您调用子项的toString()。这里没有问题,只是在这里调用父级的toString()。它将调用子对象的toString(),等等 漂亮的无限循环 最好的方法是将toString()方法更改为: public class Category { private Category parentCategory; private Set<Category>
System.out.println
正在生成stackOverflowerError
当您执行toString()
时,您调用子项的toString()
。这里没有问题,只是在这里调用父级的toString()
。它将调用子对象的toString()
,等等
漂亮的无限循环
最好的方法是将toString()
方法更改为:
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);
}
通过这种方式,您不打印parentCategory,只打印其名称,没有无限循环,没有StackOverflower错误
编辑:正如Bolo在下面所说,您需要检查parentCategory是否为null,如果为null,则可能存在NullPointerException
资源:
Category#toString()
都会产生大量其他toString
s。请注意,打印childCategories
会导致打印出每个元素(通过toString
),这反过来会重复许多toString
方法调用的整个过程
不仅如此,每个子项都在其父项上调用toString
,而父项又在其子项上调用toString
,子项又在其父项上调用toString
,而父项又在其子项上调用toString
@Override
public String toString() {
return "Category [childCategories=" + childCategories + ", name="
+ name + ", parentCategory=" + parentCategory.getName() + "]";
}
您正在使用类似于parentCategory
的实例连接到您的toString。它将调用这些实例的toString方法
toString调用的循环永远不会结束。因为子类别将调用父类别,父类别将再次调用子类别,所以
如果您输入:
System.out.println(myObject),则不是这样代码>它实际上是:System.out.println(myObject.toString())代码>由于错误是系统.out.println
问题一定是在toString()中
问题是toString()
使用其toString()
方法为您打印的对象同时打印父对象和子对象Category
。因此,当您打印一个类别时,它在父对象上调用toString()
,在子对象上调用toString()
,在父对象上调用toString()
,在子对象上调用toString()
,以此类推,直到堆栈耗尽。toString()
将进入递归尾旋。您需要有两个toString()
;一个给父母,一个给孩子。您的toString
可以如下所示:
return "Category [childCategories=" + childCategories + ", name="
+ name + ", parentCategory=" + parentCategory + "]";
stackoverflowerrror
实际上是在构建将传递给System.out.println
的String
参数时引发的
每次连接字符串
和类别
,都会执行类别
的toString()
方法。问题是类别中的toString()
有点过于冗长。解决此问题的一种方法是仅打印父类别的名称(跳过父类别和子类别):
当parentCategory==null
时,您将得到NullPointerException
。仅parentCategory.getName()
将不完整。
@Override
public String toString() {
toStringParent(parent); // This print only parent
toStringChildren(children); // This print only children
}
@Override
public String toString() {
return "Category [childCategories=" + childCategories + ", name="
+ name + ", parentCategory="
+ ((parentCategory == null) ? null : parentCategory.getName())
+ "]";
}