简体   繁体   English

为什么我不能在Java中的任何方法外部实例化?

[英]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? 请忽略我的傲慢......这几天学习Java,我遇到了一个完全相同的问题: 为什么没有main方法,为什么不能实例化和创建Object? (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. 从逻辑上考虑,遍历代码,您会看到很多new arrayprg() ...。我想到的是instantiate outside of methods并在此之后调用所有方法,但是我想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(); 我的问题,所以我有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(). 在我的程序中,每次创建一个循环时,我都会创建一个实例,但是为什么当我通过new Arrayprg().调用函数时会调用此实例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(); 我的意思是,当我通过方法内部的new Arrayprg()调用函数时,为什么Arrayprg ag = new Arrayprg(); getting called and creating the loop of error for Stackoverflow????? 被调用并为Stackoverflow创建错误循环?????

This will cause a StackOverflowError. 导致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. 当实例化一个新的Arrayprg将调用任何对象初始化程序, 包括 new Arrayprg() ,然后将递归地尝试使调用构造函数的过程没有结束。 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, 更好的是,只是不要在main方法之外创建Arrayprg ,因为Arrayprg不需要Arrayprg本身的实例,

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(); 每次创建Arrayprg实例时,都调用以下行: 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().' 同样,在您的方法(declareArr,assignArr等)中,您可以删除“ 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. 作为用Java构造对象的一部分,所有成员变量初始化器,初始化器代码块等以及构造函数本身都将被调用。

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. 因此,为了创建一个新的Arrayprg,它要做的一件事情就是寻找需要初始化和初始化它们的成员变量。

In this case it finds Arrayprg a = new Arrayprg(); 在这种情况下,它将找到Arrayprg a = new Arrayprg(); , so in order to initalise the field a , it tries to create a new Arrayprg() . 因此,为了初始化字段a ,它尝试创建一个新的Arrayprg()

But that new Arrayprg() goes through the exact same process again, and again, and again, etc. 但是,新的Arrayprg()一次又一次地经过完全相同的过程, Arrayprg()

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. 将Arrayprg作为参数传递给构造函数-因此不需要创建一个新的数组。
  2. Make the Arrayprg static - so only a single one needs to be created once rather than creating a new one each time 将Arrayprg设为静态-因此只需一次创建一个,而不是每次都创建一个
  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. Arrayprg上的惰性初始化,因此仅在第一次尝试访问它时创建它,而不是在创建父Arrayprg时创建它。

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 ? 那么,您需要创建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. 再一次,您要告诉JVM给您另一个Arrayprg对象。 By definition, this means making another Arrayprg object. 根据定义,这意味着制作另一个Arrayprg对象。

This is giving you a StackOverflowException . 这给你一个StackOverflowException

Solution? 解?

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. 按照这种模式,您将不需要Arrayprg字段。

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. 以此为准。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能在任何方法外创建对象 - Why can't I create object outside any method 为什么我不能在Java中实例化扩展类的实例? - Why can't I instantiate an instance of an extended class in Java? Java帮助:为什么我不能访问当前主方法文件之外的类中声明的静态方法 - Java Help: why can't I access the static methods declared in a class outside the current main method file 为什么不能在Java中的方法外部声明和初始化数组? - Why can't you declare and initialize an array outside of a method in java? 为什么我不能在声明方法之外访问本地类? - Why can't I access local class outside declaring method? 为什么我不能在方法之外进行赋值? - Why can't I do assignment outside a method? 为什么我不能在类之外的方法中使用数组? - Why can't I an array in a method outside its class? 为什么我不能在Android上实例化这个片段? - Why can't I instantiate this Fragment on Android? 无法实例化main()方法中的字段(实例变量)。 为什么?? 爪哇 - Can't Instantiate Field (instance variable) in main() method. Why?? Java 为什么我们不能在没有匿名类方法的情况下在java中实例化接口或抽象类? - Why can't we instantiate an interface or an abstract class in java without an anonymous class method?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM