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

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

11 голосов
/ 29 августа 2010
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.

Ответы [ 6 ]

17 голосов
/ 29 августа 2010

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

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

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

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

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

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


Ресурсы:

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

2 голосов
/ 29 августа 2010

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

@Override
public String toString() {
     toStringParent(parent);   // This print only parent
     toStringChildren(children);  // This print only children
}
2 голосов
/ 29 августа 2010

Так как ошибка System.out.println, проблема должна быть в toString().

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

1 голос
/ 29 августа 2010

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

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

@Override
public String toString() {
    return "Category [childCategories=" + childCategories + ", name="
            + name + ", parentCategory="
            + ((parentCategory == null) ? null : parentCategory.getName())
            + "]";
    }
1 голос
/ 29 августа 2010
return "Category [childCategories=" + childCategories + ", name="
                + name + ", parentCategory=" + parentCategory + "]";

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

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

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

1 голос
/ 29 августа 2010

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

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

...