pbajpai
pbajpai

Reputation: 1369

Getting StackOverflowError when define instance variable of same class containing main() method

I tried to search the answer on google but didn't find. Why below program is giving StackOverflowError.

public class HelloWorld {
    private HelloWorld obj = new HelloWorld();  // (HelloWorld.java:2)

    public static void main(String args[]) {
        HelloWorld obj = new HelloWorld();
        obj.printHello();
    }

    private void printHello(){
        System.out.println("Hello world");
    }
}

Output:

Exception in thread "main" java.lang.StackOverflowError
    at HelloWorld.<init>(HelloWorld.java:2)
    at HelloWorld.<init>(HelloWorld.java:2)
    ....................

If I comment the instance variable obj, then program prints "Hello world" and there is no error. See below:

public class HelloWorld {
//    private HelloWorld obj = new HelloWorld();

    public static void main(String args[]) {
        HelloWorld obj = new HelloWorld();
        obj.printHello();
    }

    private void printHello(){
        System.out.println("Hello world");
    }
}

Output:

Hello world

Upvotes: 2

Views: 72

Answers (4)

Amit Bera
Amit Bera

Reputation: 7315

If you look on the byte code generated by the compiler you can see that your code is compiled to similar to the below code.

public class HelloWorld {
    private HelloWorld obj;  // (HelloWorld.java:2)

    public HellowWorld(){
       obj = new HelloWorld(); // obj created in the constructor. Point-1
    }

    public static void main(String args[]) {
        HelloWorld obj = new HelloWorld();
        obj.printHello();
    }

    private void printHello(){
        System.out.println("Hello world");
    }
}

So, if you look at the point-1, you can see new HelloWorld() call leads to a recursive call without any termination condition which will lead to StackOverflow.For your reference below is the byte code:

public class abc.HelloWorld {
  public abc.HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: new           #1                  // class abc/HelloWorld
       8: dup
       9: invokespecial #12                 // Method "<init>":()V
      12: putfield      #13                 // Field obj:Labc/HelloWorld;
      15: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #1                  // class abc/HelloWorld
       3: dup
       4: invokespecial #12                 // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: invokespecial #20                 // Method printHello:()V
      12: return
}

Upvotes: 1

Sweeper
Sweeper

Reputation: 271060

When creating a new instance of a class, like you are doing in the main method:

HelloWorld obj = new HelloWorld();

That class's instance variables' variable initialisers get executed, which in the case of HelloWorld, is this line here:

private HelloWorld obj = new HelloWorld();  // (HelloWorld.java:2)

That line creates another HelloWorld instance, which causes that same line to run again. To run that line again, another instance would need to be created, which means that same line has to run again, and again, and so on...

Another way to think of this is to imagine HelloWorld to have a constructor like this:

class HelloWorld {
    private HelloWorld obj;
    public HelloWorld() {
        obj = new HelloWorld();
    }
}

You should clearly see the infinite recursion happening.

Upvotes: 0

Sabareesh Muralidharan
Sabareesh Muralidharan

Reputation: 647

Yes, it would throw StackOverFlowException because when you do,

HelloWorld obj = new HelloWorld();

inside your main, your class will be initialized and it would reach line 2, from there it would try to initialize HelloWorld again and it reached line 2... the cycle goes on.

This can happen even if do not use same name for your objects too.

public class HelloWorld {
    private HelloWorld obj = new HelloWorld();  // (HelloWorld.java:2)

    public static void main(String args[]) {
        HelloWorld obj = new HelloWorld();
        obj.printHello();
    }

    private void printHello(){
        System.out.println("Hello world");
    }
}

Upvotes: 1

aballaci
aballaci

Reputation: 1083

It is a cyclic instantiation error. No wonder!

Upvotes: 1

Related Questions