Why is this toString() method causing StackOverFlowError?

Rahul Gupta :

I have understood from this and this answer, the possible scenarios where your code could get into an infinite loop resulting into stackOverFlowError but I don't understand how the same scenario is getting replicated here,

public class A {
  private B b = new B();
  @Override
  public String toString() {
      return "b "+b;
  }
}

public class B {
  private A a = new A();
  @Override
  public String toString() {
      return "";
  }
}

public class StackoverflowErrorTest {
  public static void main(String[] args) {
     A a = new A();
     System.out.println(a);
  }
}

This code is generating below stack trace:-

Exception in thread "main" java.lang.StackOverflowError
at stackoverflowerror.B.<init>(B.java:5)
at stackoverflowerror.A.<init>(A.java:5)
.
.
.

As per my understanding, When I am printing object 'a' in the main method, it will invoke the toString method of A class, in that method I am returning the object of B class which would implicitly call the toString method of B class. Now, in the toString method of B class, all I am returning is an empty string. Then how and where is the scope of infinite loop coming into picture here. Please explain.

Nikolas :

It enters the endless cycle of events. The method toString() is innocent in this case:

  1. The method main creates an instance of the class A
  2. The class A creates an instance of the class B upon initialization
  3. The class B creates an instance of the class A upon initialization
  4. Go to the step 2

The local variables are allocated on the stack and the StackOverflowError is a result of a bad recursive call.

Thrown when a stack overflow occurs because an application recurses too deeply.

Recommended solution, remove the reference to the class A in the class B because it's unused:

public class B {

    @Override
    public String toString() {
        return "";
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=37155&siteId=1