简体   繁体   English

Stack Overflow java

[英]Stack Overflow java

Object as a class variable causes the stackoverflow 作为类变量的对象会导致堆栈溢出

public class stack {
        stack obj = new stack();   // its obvious that during class loading obj will call class to
        // load and infinite loop will occur. 
}

Lets say i am using static in from class obj 假设我在类obj中使用static

public class stack {
      static stack obj = new stack();  // it will not cause infinite loop and program will //execute successfully
}

Static variables are allocated in to the memory when the class is caught by JVM first time (As far I know). 当JVM第一次捕获类时,静态变量被分配到内存中(据我所知)。 Say during first time only if the JVM starts allocating the memory to the above static object variable. 仅在JVM开始将内存分配给上述static对象变量时才说。 It will intern call the class again and this should also cause infinite loop . 它会再次实际调用该类,这也应该导致无限循环。 Somewhere i am wrong. 在某个地方我错了。 Can somebody highlight where i am wrong. 有人可以突出我错在哪里。

No, declaring it as static won't cause an infinite loop. 不,将其声明为static不会导致无限循环。 Here is why. 这就是原因。

Static variables are initialized during the class loading time. 静态变量在类加载时间内初始化。 So when your class loads for the first time, compiler will create an instance for the static variable, and that's it. 因此,当您的类第一次加载时,编译器将为静态变量创建一个实例,就是这样。 This won't cause your class to load a second time. 这不会导致您的班级第二次加载。 Since your class is not loading again, this process won't be repeated. 由于您的课程没有再次加载,因此不会重复此过程。

If you declare it as a non-static attribute, then it's a totally different story. 如果你将它声明为非静态属性,那么这是一个完全不同的故事。 Consider this - 考虑一下 -

public class stack {
    stack obj = new stack();

    ........
}

This declaration is equivalent to - 该声明相当于 -

public class stack {
   stack obj;

    public stack() {
        obj = new stack();    // implicitly moved here by the compiler
    }

    ........
}

From the last example, it's pretty obvious why there is an infinite recursion here. 从最后一个例子可以看出,为什么这里存在无限递归。 You are creating an instance of the stack class inside its own constructor, which in turn creates another, and then another,......and it goes on, resulting in a Stack Overflow. 您正在其自己的构造函数中创建stack类的实例,该构造函数又创建另一个,然后另一个,......然后它继续,导致堆栈溢出。

Loading the "stack" class will induce creating an instance of "stack", saved as static field the stack class. 加载“stack”类将导致创建“stack”的实例,将其保存为堆栈类的静态字段。 Then, this instance of the stack class has nothing to load: No stack exception. 然后,堆栈类的这个实例无需加载:没有堆栈异常。

keyword Static has nothing to do with infinite loop. 关键字Static与无限循环无关。 You can declare the field, method,class(static inner class) 你可以声明字段,方法,类(静态内部类)

Static Field :- Static fields are created and initialized when the class is first loaded. 静态字段: -首次加载类时,会创建并初始化静态字段。 That happens when a static member of the class is referred to or when an instance of the class is created, whichever comes first. 当引用类的静态成员或创建类的实例时(以先到者为准),就会发生这种情况。

Static method:- A method declared with the static keyword. 静态方法: -使用static关键字声明的方法。 Like static fields, static methods are associated with the class itself, not with any particular object created from the class. 与静态字段一样,静态方法与类本身相关联,而不是与从类创建的任何特定对象相关联。 As a result, you don't have to create an object from a class before you can use static methods defined by the class. 因此,在使用类定义的静态方法之前,不必从类创建对象。

The best-known static method is main, which is called by the Java runtime to start an application. 最着名的静态方法是main,由Java运行时调用以启动应用程序。 The main method must be static, which means that applications run in a static context by default. main方法必须是static,这意味着默认情况下应用程序在静态上下文中运行。

Memory Perspective:- As class is loaded once and its definition is stored in permgen area of jvm, static variables are also stored there and will lie for the life cycle of jvm. 内存透视: -由于类被加载一次并且其定义存储在jvm的permgen区域中,静态变量也存储在那里并且将在jvm的生命周期中存在。

Static variables are allocated in to the memory when the class is caught by JVM first time 当JVM第一次捕获类时,静态变量将分配给内存

Not exactly. 不完全是。

The static variables are allocated when the class is loaded. 加载类时会分配静态变量。

The static variable initialization is performed when the class is initialized. 初始化类时执行静态变量初始化。 That may happen some time after the class is loaded. 这可能发生在加载类之后的某个时间。

Say during first time only if the JVM starts allocating the memory to the above static object variable. 仅在JVM开始将内存分配给上述静态对象变量时才说。 It will intern call the class again and this should also cause infinite loop. 它会再次实际调用该类,这也应该导致无限循环。

No. This is wrong for two reasons: 不,这有两个原因:

  • Objects in general are not "interned". 通常,对象不是“实习”。 Interning is an operation on String objects, and even then it only happens automatically for String literals. Interning是对String对象的操作,即使这样,它也只对String文字自动发生。 Non-literal String objects only get interned if your application calls String.intern() explicitly on them. 如果应用程序在其上显式调用String.intern()则非文字String对象只会被实现。

  • Even if some kind of interning was performed automatically, this would not cause an infinite loop. 即使自动执行某种实习,也不会导致无限循环。 You seem to think that interning would somehow cause class initialization to be restarted or repeated. 您似乎认为实习会以某种方式导致类初始化重新启动或重复。 That cannot happen, the JVM goes to considerable lengths to ensure that each class is initialized at most once during its lifetime. 这是不可能的,JVM需要相当长的时间才能确保每个类在其生命周期内最多初始化一次。

During debugging we can get to know , when first time control comes to the static variable , as variable is nothing but an instance of the class , it will call class loading . 在调试期间,我们可以知道,当第一次控制到达静态变量时,因为变量只是类的一个实例,它将调用类加载。

then control enters in to the class , and finds a static variable object , but by this time it would be assigned by a memory address value by JVM(as done to other static variables). 然后控件进入类,并找到一个静态变量对象,但此时它将由JVM分配一个内存地址值(与其他静态变量一样)。 Control just ignores variable as instance and it assumes purely as static and program continues. Control只是忽略变量作为实例,它纯粹假定为静态,程序继续。

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

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