【问题标题】:Why I'm getting StackOverflowError为什么我收到 StackOverflowError
【发布时间】:2010-08-29 07:17:59
【问题描述】:
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

【问题讨论】:

    标签: java stack-overflow


    【解决方案1】:

    当你做你的toString()时,你打电话给孩子们的toString()。除了在这里调用父级的toString() 之外,这里没有问题。这将调用孩子的toString() 等。

    漂亮的无限循环。

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

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

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

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


    资源:

    关于同一主题:

    【讨论】:

    • parentCategory == null 时,你会得到NullPointerException
    • 只是parentCategory.getName() 不完整。
    【解决方案2】:

    由于错误是System.out.println,所以问题一定出在toString()

    问题是toString() 使用toString() 方法打印父对象和子Category 对象。因此,当您打印类别时,它会在父级上调用toString(),在子级上调用toString(),在父级上调用toString(),在子级上调用toString(),依此类推,直到堆栈耗尽。

    【讨论】:

      【解决方案3】:

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

      不仅如此,每个孩子都在其父级上调用toString,而后者又在其子级上调用toString,每个子级对父级调用toString,而后者又在其子级上调用toString,哪个...

      【讨论】:

        【解决方案4】:
        return "Category [childCategories=" + childCategories + ", name="
                        + name + ", parentCategory=" + parentCategory + "]";
        

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

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

        如果你输入:System.out.println(myObject); 实际上是:System.out.println(myObject.toString());

        【讨论】:

          【解决方案5】:

          您的toString() 将进入递归尾旋。你需要有两个toString();一份给父母,一份给孩子。您的toString 可能如下所示:

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

          【讨论】:

            【解决方案6】:

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

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

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

            【讨论】:

              猜你喜欢
              • 2021-08-10
              • 2017-12-21
              • 2016-09-11
              • 1970-01-01
              • 2017-08-17
              • 2020-09-18
              • 2012-05-27
              • 2020-03-09
              • 2020-04-08
              相关资源
              最近更新 更多