Почему я получаю StackOverflowError

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 .

11
задан jai 29 August 2010 в 07:17
поделиться

6 ответов

Когда вы выполняете toString(), вы вызываете toString() дочерних элементов. Здесь нет проблем, за исключением того, что здесь вы вызываете toString() родителя. Который вызовет toString() дочерних элементов и т.д.

Хороший бесконечный цикл.

Лучший способ избавиться от него — изменить метод toString() на :

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

Таким образом, вы не печатаете parentCategory, а только его имя, без бесконечного цикла, без StackOverflowError. .

РЕДАКТИРОВАТЬ: Как сказал Боло ниже, вам нужно будет проверить, что parentCategory не является нулевым, у вас может быть NullPointerException, если это так.


Ресурсы:

По той же теме:

17
ответ дан 3 December 2019 в 04:30
поделиться

Поскольку ошибка заключается в System.out.println, проблема должна быть в toString().

Проблема в том, что toString() печатает как родительский, так и дочерний объект Category для той, которую вы печатаете, используя их метод toString(). Поэтому, когда вы печатаете категорию, она вызывает toString() для родителя, который вызывает toString() для дочернего элемента, который вызывает toString() для родителя, который вызывает toString() для дочернего элемента и так далее, пока стек не будет исчерпан.

2
ответ дан 3 December 2019 в 04:30
поделиться

StackOverflowError на самом деле возникает при построении аргумента String, который будет передан в System.out.println.

Каждый раз, когда вы объединяете String и Category, выполняется метод toString() для Category. Проблема в том, что ваш toString() в Категории слишком многословен. Один из способов исправить это — напечатать только название родительской категории (пропустив родительскую и дочернюю категории):

@Override
public String toString() {
    return "Category [childCategories=" + childCategories + ", name="
            + name + ", parentCategory="
            + ((parentCategory == null) ? null : parentCategory.getName())
            + "]";
    }
1
ответ дан 3 December 2019 в 04:30
поделиться

Ваш toString() входит в рекурсивный штопор. Вам нужно иметь два toString(); один для родителей и один для детей. Ваш toString может выглядеть так:

@Override
public String toString() {
     toStringParent(parent);   // This print only parent
     toStringChildren(children);  // This print only children
}
2
ответ дан 3 December 2019 в 04:30
поделиться

Потому что каждый вызов Category#toString() порождает массу других toString. Обратите внимание, что печать childCategories приводит к выводу каждого элемента (через toString), что, в свою очередь, повторяет весь этот процесс из множества вызовов метода toString.

Мало того, каждый дочерний элемент вызывает toString для своего родителя, который, в свою очередь, вызывает toString для своих дочерних элементов, каждый из которых вызывает toString для родительского элемента. , который, в свою очередь, вызывает toString для своих дочерних элементов, что...

1
ответ дан 3 December 2019 в 04:30
поделиться
return "Category [childCategories=" + childCategories + ", name="
                + name + ", parentCategory=" + parentCategory + "]";

вы используете такие экземпляры, как parentCategory для присоединения к вашей toString. он вызовет метод toString этих экземпляров.

этот цикл вызовов toString никогда не заканчивается. потому что дочерняя категория вызовет родительскую категорию, а родительская снова вызовет дочернюю и так далее...

не то, что если вы поместите: System.out.println(myObject); на самом деле это: System .out.println(myObject.toString());

1
ответ дан 3 December 2019 в 04:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: