2010-08-29 14 views
9
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); 
    } 

El System.out.println está generando la StackOverflowError.¿Por qué estoy recibiendo StackOverflowError

Respuesta

14

Cuando haga su toString(), llame al toString() de los niños. No hay problema aquí, excepto que llame al toString() del padre aquí. Que llamará al toString() de los niños, etc.

Bonito bucle infinito.

La mejor manera de deshacerse de él es cambiar su método de toString() en:

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

De esta manera no se imprime el parentCategory sino sólo su nombre, sin bucle infinito, sin StackOverflowError.

EDIT: Como dijo Bolo a continuación, tendrá que comprobar que parentCategory no es nulo, es posible que tenga NullPointerException si es así.


Recursos:

Sobre el mismo tema:

+0

Usted obtendrá '' NullPointerException' lugar cuando parentCategory == null'. – Bolo

+0

Simplemente 'parentCategory.getName()' no estará completo. – fastcodejava

1

Debido a que cada llamada a Category#toString() produce una tonelada de otras toString s. Observe que imprimir childCategories hace que cada elemento se imprima (a través de toString), que a su vez repite todo este proceso de muchas llamadas al método toString.

No sólo eso, sino que cada niño llama toString en su padre, que a su vez llama a toString de sus hijos, lo que llaman cada toString en la matriz, lo que a su vez llama toString de sus hijos, que ...

1
return "Category [childCategories=" + childCategories + ", name=" 
       + name + ", parentCategory=" + parentCategory + "]"; 

está utilizando instancias como parentCategory para concat a su toString. llamará al método String de estas instancias.

este bucle de llamadas toString nunca termina. porque Categoría niño va a llamar Categoría de Padres y Padres de Childs llamará de nuevo y así ...

no que si se pone: System.out.println(myObject); lo que realmente es: System.out.println(myObject.toString());

2

Puesto que el error es el System.out.println el problema debe estar en el toString().

El problema es que toString() imprime objetos tanto primarios como secundarios Category para su impresión utilizando su método toString().Por lo tanto, cuando imprime una Categoría, llama al toString() en el padre que llama al toString() en el hijo que llama al toString() en el elemento primario que llama al toString() en el elemento secundario y así sucesivamente hasta que se agote la pila.

2

Su toString() entra en una deriva recursiva. Necesita tener dos toString(); uno para el padre y otro para los niños. Su toString puede tener este aspecto:

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

StackOverflowError se planteó realmente mientras que la construcción del argumento String que se transmitiría a System.out.println.

Cada vez que concatenas String y Category, se ejecuta el método toString() de Category. El problema es que su toString() en Category es un poco demasiado detallado. Una forma de solucionarlo es imprimir sólo el nombre de la categoría padre (se pierden es de los padres y niños):

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