简体   繁体   中英

Why can't I instantiate outside any method in java?

Please ignore my arrogance......learning java these days, i came across this perfectly same question for my problem : Why can't I instantiate and create Object without main method? (Stack Overflow Error)

Expecting a possible downvote too...but please go through my question once!!!!

Code that i was trying :

public class Arrayprg{

    Arrayprg ag = new Arrayprg(); //ignore this for a while and go thru code please    

     public static void main(String []args){
        System.out.println("Hello Array");
        new Arrayprg().declarearray();
     }


     public void  declarearray()
     {
         int[] arr;
         arr = new int[11];
         new Arrayprg().assignarr(arr);
     }


     public void  assignarr(int arr[])
     {
         int i;
         for(i = 0; i < 11; i++)
         {
             arr[i] = i;
         }
         new Arrayprg().printarr(arr);
     }

     public void  printarr(int arr[])
     {
         int i;
         for(i = 0; i < 11; i++)
         {
             System.out.println(arr[i]);
         }
     }
}

Thinking logically, going through the code you'll see lots of new arrayprg() ....what i thought of was to instantiate outside of methods and calling all methods through it there after, but i guess it is not allowed in java.

Whats causing my Problem

Going by the solution in quoted question, as it explain that below thing happens :

 Create new instance of Arrayprg
      -> ag = Create new instance of Arrayprg
          -> ag = Create new instance of Arrayprg
             -> ag = Create new instance of Arrayprg

Explanation given in that question
.....it is initialized whenever an instance of the class is instantiated. This will never terminate until you run out of memory and get the stack overflow. Run it with a debugger for a clearer view.

My Question so i have Arrayprg ag = new Arrayprg(); in my program which is creating a loop every-time i create an instance but why is this called when i am calling the functions through new Arrayprg().

What i mean is that when i am calling the function through new Arrayprg() inside the methods why is Arrayprg ag = new Arrayprg(); getting called and creating the loop of error for Stackoverflow?????

This will cause a StackOverflowError.

The line you tell us to ignore, interestingly, is the culprit. When you instantiate a new Arrayprg then any object initializers are called, including new Arrayprg() which will then recursively try to keep invoking constructors without end. Remove that line, or put it in a static initializer. Better yet, just don't create that Arrayprg outside the main method as your Arrayprg does not need an instance of Arrayprg itself,

I would be more clear but I don't know what you're trying to achieve.

Every time you create an instance of Arrayprg , you call this line: Arrayprg = new Arrayprg(); , this means every time you create one, it creates another and another and another etc. You can instantiate objects there, but instantiating another object of the same type causes your infinite loop.

Also, in your methods (declareArr, assignArr etc) you can remove the 'new Arrayprg().' and just call the functions on the existing object.

Solution :

Change this line:

Arrayprg = new Arrayprg(); //ignore this for a while and go thru code please    

to:

static Arrayprg a = new Arrayprg();

And you will no longer get your infinite recursion problem as now it will only create one instance of it shared between all instances - rather than each instance immediately creating a new one.

The Explanation

As part of constructing an Object in Java all member variable initializers, initializer code blocks, etc are all called as well as the constructor itself.

So in order to create a new Arrayprg one of the things it does is look for member variables that need initializing and initialize them.

In this case it finds Arrayprg a = new Arrayprg(); , so in order to initalise the field a , it tries to create a new Arrayprg() .

But that new Arrayprg() goes through the exact same process again, and again, and again, etc.

There are a number of ways to fix this - including:

  1. Pass in the Arrayprg as a parameter to the constructor - so a new one doesn't need to be created.
  2. Make the Arrayprg static - so only a single one needs to be created once rather than creating a new one each time
  3. Lazy initaliziation on the Arrayprg so that you only create it the first time you try and access it rather than when the parent Arrayprg is created.

Why it doesn't happen in a method call:

The important thing that causes the recursion here is that the call happen during the creation of a new object. If trying to create a new object involves creating another copy of the same object then you will end up with infinite recursion which will then cause the failure.

So you can create a new object anywhere you like - so long as it is not inside the creation of itself.

class A {
     A a = new A(); // Recursion
}

class A {
     A() {
         A a = new A(); // Recursion
     }
}

class A {
     A getNewA() {
         return new A();
         // This is fine as it doesn't happen during creation of an A
     }
}

class A {
     A() {
         getNewA(); 
         // Recursion as calling getNewA creates a new A, which calls getNewA, which....
     }

     A getNewA() {
         return new A(); 
         // This is fine on its own but is broken if called from the constructor
     }
}

class B {
     A a = new A(); 
     // This is fine as B is not A, so you can create a new A within B.
}

Let's step through this visually.

Arrayprg = new Arrayprg();

So what do you need to create an object of type Arrayprg ? Well you need to create it's fields.

Arrayprg = new Arrayprg();

And once again, you're telling the JVM to give you another Arrayprg object. By definition, this means making another Arrayprg object.

This is giving you a StackOverflowException .

You shouldn't really be nesting types like this. It's pointless. You're inside the class already, so use it's methods.

public void  declarearray()
{
     int[] arr;
     arr = new int[11];
     assignarr(arr);
}

Follow this pattern, and you'll eliminate the need for the Arrayprg field.

In a class you can create objects outside any method, object cannot be of the same class.

It is meaningless. Take it as a rule.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM