Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this toString() method causing StackOverFlowError? [duplicate]

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.

like image 285
Rahul Gupta Avatar asked Jul 27 '18 10:07

Rahul Gupta


People also ask

What causes Java Lang StackOverflowError?

StackOverflowError is a runtime error which points to serious problems that cannot be caught by an application. The java. lang. StackOverflowError indicates that the application stack is exhausted and is usually caused by deep or infinite recursion.

Why toString method is overridden?

It is because this method was getting automatically called when the print statement is written. So this method is overridden in order to return the values of the object which is showcased below via examples.

Can toString be overloaded?

Overloading the ToString method ToString() method, many types overload the ToString method to provide versions of the method that accept parameters. Most commonly, this is done to provide support for variable formatting and culture-sensitive formatting.


1 Answers

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 "";
    }
}
like image 83
Nikolas Charalambidis Avatar answered Oct 23 '22 14:10

Nikolas Charalambidis