In-depth JVM (2): Check the initialization of Java classes and objects by a stack overflow problem

Source: Internet
Author: User

Today, some netizens in A group asked the following question: Why is the stack overflow (StackOverflowError) caused by the code called for running:

public class Constructor {    Constructor c = new Constructor();    public static void main(String[] args) {        Constructor test = new Constructor();    }}
Ordinary people, at first glance, do not feel any problem, but if they run on the machine, such an error will pop up,
 
 
From these errors, we can get the following information: when the program is running, the Constructor instance Initialization Method
(Here is <init>, which will be detailed later.
 
The people in the group replied to this question. One of the netizens pushed the result through the symptom and said, "In this Constuctor class, because the member c of the class is actually
Constructor type, so when class members are initialized, the class Constructor is called recursively ".
 
The answer is, to be honest, no logic. It seems like I am confused. In fact, if we start with the bytecode of this class after disassembly,
You can get the answer to the question clearly.
We use java-p Constructor to obtain the deserialization bytecode, as follows:
public class Constructor extends java.lang.Object{
Constructor c;

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

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

}
 
 
 
We only need to pay attention to the Code in Constructor of this Constructor. We can find that in this Constructor,
The new #1; // class Constructor statement is displayed, which indicates creating a Constructor type object.
 
From here we can understand:
Even if you initialize a member such as c explicitly outside the constructor, but when the class is compiled and run,
The real initialization of such Explicit initialization members is still carried out in the constructor in a unified manner.
 
So the code like the one just now is equivalent to calling itself in the Constructor, just like the following code:
Public class Constructor {

Constructor c;

Public Constructor (){
C = new Constructor ();
}

Public static void main (String [] args ){
Constructor test = new Constructor ();

}
}
How can you avoid stack overflow?

PS: By the way, the meaning of several Bytecode commands is as follows:
Create a new object.

Invokespecial calls the instance method based on the compile-time type.
Invokevirtual calls the instance method based on the actual type of the runtime object.
Putfield sets the field value in the object.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.