L
L
LaYof2016-07-07 17:19:53
Java
LaYof, 2016-07-07 17:19:53

How to fix a specific case with stackoverflow? How to understand java?

Tell me, please, why, damn it, the classes in this example depend on each other.
Or rather, the Lois class from the Pitter class. The problem is that a stack overflow occurs and the program throws an error. I am a beginner and please do not swear for my possibly stupid mistakes.eb586b323b8749eaa96e5c47a8ce9e14.jpg78f8ab6d2f634772ac181bc223904bf1.jpg

Answer the question

In order to leave comments, you need to log in

3 answer(s)
P
pi314, 2016-07-07
@LaYof

These classes depend on each other, because one creates an instance of the other, and vice versa. In itself, this is not scary, but it happens to you both there and there right in the initialization (the place where the fields are declared and they are immediately assigned a new instance of another class).

public class Lois {
  Pitter husbend = new Pitter();
  ...

public class Pitter {
  Lois wife = new Lois();
...

Initialization is performed whenever an instance of this class is created:
...  = new Lois();
 //or
    ... = new Pitter();

moreover, it does not matter where and why the program tries to create it.
Accordingly, an attempt (initially - somewhere else in the program) to create an instance of any of these classes leads to the fact that for this it will first be necessary to create a new instance of the second, which will require the creation of a new instance of the first, and so on. to infinity. As a result, this very first attempt will never end ... or rather, end with a stack overflow.
What is a stack overflow and why does it happen here? Any creation of an object (instance of a class) "inside" simply means "calling a method" (static initialization, then the constructor; only after the return from the constructor is the object considered created and the instance reference can be assigned to something there). And "method call" means (slightly simplified) nothing more than "put on the stack the return point, the method's passed parameters, and jump to the address of the method". The method takes the parameters and the return point from the stack, puts its result (if any) on the stack at the end, and jumps over the return point. If it's followed by an assignment in the program (as in your classes), the result is popped off the stack and "assigned". Thus, in a normal call, the stack remains "clean". And if the call goes into an endless chain of other calls, like yours, then it never comes to cleaning, and the stack ends sooner or later. That's when the StackOverflowError arrives.
Simplified, the essence of what is happening in you can be illustrated like this:
public class Main {

  public static void main(String[] args) {
    // You can run JVM with:
    //	-XX:MaxJavaStackTraceDepth=-1 (unlimited number of stack trace frames)
    //  -Xss4m (play around with stack size)
    //
    try {
      first(); // causes stack overflow!
    } catch (StackOverflowError e) {
      System.err.println("Depth (frames):" + e.getStackTrace().length);
    }
  }
  
  static int first(){
    return second();
  }

  static int second(){
    return first();
  }
}

You can run it and see what happens :)
To prevent this from happening, you need to redo the code, for example, like this:
public class Lois {

  Pitter myHusband = new Pitter(this);
  
  public Lois(Pitter whoIsMyHusband){
    myHusband = whoIsMyHusband;
  }
  
  //...
}

public class Pitter {
  
  Lois myWife = new Lois(this);
  
  public Pitter(Lois whoIsMyWife) {
    myWife = whoIsMyWife;
  }
  
  // ...
}

V
void_phoenix, 2016-07-07
@void_phoenix

Most likely, when creating Lois, new Pitter is called, when it is created, new Lois is called, when it is created, new Pitter is called ... Repeat until the stack overflows.

L
LaYof, 2016-07-08
@LaYof

Here is the Pitter classc64606b4caa2422992c104fdb072fc22.png

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question