Initialization of classes in Java

Source: Internet
Author: User
Tags array definition

Class starts from being loaded into the virtual machine's memory, and its entire lifecycle includes: load, validate, prepare, parse, initialize, use, and unload seven phases, until the memory is unloaded. Where validation, preparation, parsing 3 parts collectively referred to as the connection. The process of class loading includes five stages of loading, validating, preparing, parsing, and initializing.

When loading, validating, preparing, initializing, and unloading the sequence of these 5 phases, the loading process of a class must begin in this order, and the parsing phase is not necessarily, and in some cases it can start after the initialization phase, This is to support runtime bindings for the Java language (also become dynamic bound or late bound). Also note that the stages here are started in order, rather than sequentially or in order, because these phases are usually mixed in a cross-section, often invoking or activating another phase during one phase of execution.

Class initialization is the last phase of the class loading process, and in the initialization phase, the Java program code in the class is actually started. The virtual machine specification strictly specifies that there are only 5 cases in which the class must be initialized immediately:

  • first : When encountering the four bytecode directives of new, getstatic, putstatic, Invokestatic, if the class has not yet been initialized, it needs to trigger its initialization first. The most common Java code scenario for generating these four instructions is when instantiating an object with the New keyword, when reading or setting a static field (static) of a class (except for static fields that have been put into the constant pool at compile time by static decoration and final decoration), And when a static method of a class is called.
  • Second: When you make a reflection call to a class using the Java.lang.refect package method, you need to trigger its initialization first if the class has not been initialized.
  • Third : When initializing a class, it is necessary to trigger the initialization of its parent class if it finds that its parent class has not yet been initialized.
  • The fourth type: when the virtual machine starts, the user needs to specify a main class to execute, and the virtual opportunity executes the main class first.
  • The fifth type: When using JDK1.5 support, if a java.langl.incoke.MethodHandle instance finally resolves the result ref_getstatic, Ref_putstatic, ref_invokestatic method handle, And the class that corresponds to the method handle is not initialized, it needs to be initialized first.

The virtual machine specifies that there are only 5 cases that trigger the initialization of the class, and the behavior in the 5 scenario is called an active reference to a class, except that all references to the class do not trigger its initialization, called a passive reference. Here are some examples to illustrate passive references.

1. References a static field in the parent class through a subclass, when the reference to the child class is a passive reference, so the subclass is not initialized, only the parent class is initialized
Package org.wrh.classupload;/* * References a static field of a parent class through a subclass and does not cause subclasses to initialize * */PublicClassTestClassDemo01 {PublicStaticvoid Main (string[] args) {TODO auto-generated Method Stub System.out.println (SUBCLASS.I);//subclass refers to the static field of the parent class}} class superclass{public static int i= 3; //the static field of the parent class static{// When this class is initialized in the virtual machine, this static block will be executed System.out.println ( "superclass init");}} class subclass extends superclass{ static{//when this class is initialized in a virtual machine, the static block is executed System.out.println (  "subclass Init"); }} 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26

The results of the program run as follows:

Superclass Init
3

That is, only "superclass init" is output, and no "subclass Init" is output.

Conclusion: For a static field, only the class that directly defines the field is initialized, so referencing the static field defined in the parent class through its subclasses will only trigger the initialization of the parent class without triggering the initialization of the subclass. Whether or not to trigger the loading and validation of subclasses is not explicitly stated in the virtual machine specification, depending on the implementation of the virtual machine.

When you instantiate an object with new, the parent class is initialized before the class itself is initialized.
Package org.wrh.classupload;/* * References a static field of a parent class through a subclass and does not cause subclasses to initialize * */PublicClassTestClassDemo01 {PublicStaticvoid Main (string[] args) {//system.out.println (SUBCLASS.I); //superclass s=new superclass (); Subclass S=new subclass ();}} class superclass{public static int i= 3; static{System.out.println ( "superclass init");}} class subclass extends superclass{ static{System.out.println ( "subclass Init");}}      
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21st
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

The results of the operation are as follows:

Superclass Init
Subclass Init

Referencing a class through an array definition does not trigger initialization of this class
package Org.wrh.classupload;public class TestClassDemo02 {public static void main (String[] args) {//TODO auto-generated Method stub superclass_1 superclass[]=new Superclass_1[5];}} Class superclass_1{static{system. Out.println ( "superclass init");}         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

does not output any content after execution, stating that no class initialization is done.

However, this code triggers the initialization of another class named "Llsuperclass_1", which is automatically generated by the virtual machine, Directly inherits from the subclass of the Java.lang.Object, the creation action is triggered by the bytecode directive NewArray, which is obviously the initialization of an array reference type.

Constants are stored in a constant pool of classes that call it at compile time, and are not inherently referenced directly to the class that defines the constant, so initialization of classes that define constants is not triggered
package Org.wrh.classupload;public class notinitialization {public static void main (String[] args) {System.< Span class= "Hljs-keyword" >out.println (Constclass.value); }}class constclass{public static final int value=3; static{system. Out.println ( "Constclass init");}         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

The results of the operation are as follows:

3

There is no output of "Constclass init", so this class is not initialized when we refer to the final modified constants.
Although the program references the constant value of the Constclass class, the value "3" of the constant is stored in the constant pool of the class constclass that called it during the compilation phase. A reference to a constant const.value actually translates to a reference to the Constclass class to its own constant pool. In other words, there is actually no symbolic reference entry for the Const class in the Constclass class file, and there is no connection to the two classes after they are translated into class files.

The loading process of the interface

The loading process of the interface is slightly different from the class loading process, there are some special instructions for the interface: The interface also has the initialization process, which is consistent with the class, the above code is the static statement block "static{}" to output the initialization information, and the interface cannot use "static{}" statement block, However, the compiler will still generate the "()" class constructor for the interface, which initializes the member variables defined in the interface. The real difference between interfaces and classes is the third of the 5 "Have and only" scenarios that you need to start initializing: When a class initializes, it requires that its parent class be initialized, but when the interface is initialized, it does not require its parent interface to complete initialization. It is initialized only when the parent interface is actually used, such as constants defined in the reference interface .

Initialization of classes in Java

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.