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())
            + "]";
    }