This is the 11th day of my participation in the August More Text Challenge. For details, see:August is more challenging

Code result?

First, let’s look at the output of the following code

/ / the resultCode to the public,Copy the code

When a class loads, static code blocks are loaded. Why is the static block in Test1 not loaded? Here’s what’s going on

Class lifecycle

Before you get into class loading, familiarize yourself with the class lifecycle

A few points to note here:

  • Parsing stageCan be found inInitialization phaseLater, this is to support the Runtime binding feature of the Java language (also known asDynamic bindingorLate binding)
  • These phases are often interlaced with each other, calling and activating one phase while the other is executing.

Initialization and instantiation

I’m sure a lot of people, like I did at the beginning, are confused about the difference between the two, is new an object, is this object initialized or instantiated?

  • Initialization: is to complete the preparation before the execution of the program. At this stage, static (variables, methods, blocks of code) are executed. At the same time, it will open up a storage space for static data. Initialization is performed only once, when the class is loaded.

  • Instantiation: The process of creating an object. In the process, you open up memory in the heap, you store non-static methods, variables. During the execution of a program, multiple objects can be created, both instantiated multiple times. Each instantiation opens up a new piece of memory.

Class initialization

The Java Virtual Machine Specification does not impose restrictions on loading, which can be left to the implementation of the virtual machine. For the initialization phase, however, the Java Virtual Machine Specification stipulates that there are only six situations in which a class must be “initialized” immediately (and loading, validation, and preparation naturally begin before that) :

  • When the bytecode instructions new, getStatic, putStatic, or InvokeStatic are encountered, if the type has not been initialized, the initialization phase needs to be triggered first. So when exactly can you generate these instructions? In fact, if you look at the bytecode, you’ll see

  • When using the java.lang.Reflect package’s methods to reflect on a type, if the type has not already been initialized, it needs to be initialized first.

  • When initializing a class, if the parent class has not been initialized, the parent class must be initialized first.

  • When the virtual machine starts, the user needs to specify a main class to execute (the class containing the main() method), which the virtual machine initializes first.

  • When using the new dynamic language support in JDK 7, If a Java lang. Invoke. The final analytical results for MethodHandle instance REF_getStatic, REF_putStatic, REF_invokeStatic, REF_newInvokeSpecial handle four kinds of methods, If the class to which the method handle corresponds has not been initialized, it needs to be initialized first.

  • When an interface defines a new default method in JDK 8 (the interface method modified by the default keyword), the interface must be initialized before any of the implementation classes of the interface are initialized.

Java. Lang. Invoke MethodHandle is JDK7 new add similar reflection function of a class

Passive reference

The Java Virtual Machine Specification uses a very strong qualifier — “have and only” — for these six scenarios that trigger type initialization. The behavior in these six scenarios is called active reference to a type. In addition, all methods of referencing types do not trigger initialization and are called passive references.

For static fields, only the class that directly defines the field is initialized. Therefore, referring to a static field defined in a parent class through its subclass triggers initialization only for the parent class and not for the subclass.

Example 1– Arrays of objects

Directly above

This code does not print gray because Test1 is not initialized. Instead, the anewarray bytecode instruction is used to initialize another class, which is automatically generated by the virtual machine and directly inherits from java.lang.Object.

Extension: Array out-of-bounds checking is not encapsulated in the array element access class, but in the array access xaload, Xastore bytecode instruction

Example 2– Static fields decorated with final

  • befinalStatic field decorated

When this Code is run, only gray Code is printed, and Test1 does not trigger the initialization phase. This is because the grey Code of the value of this constant is stored directly in the constant pool of ClassLoadTest through constant propagation optimization at compile time. So when ClassLoadTest calls value in Test1, it is a call to its own constant pool and has nothing to do with Test1.

  • Static fields without final decoration

Without a static variable decorated with final, the bytecode appears getStatic, so Test1’s initialization phase is triggered, and the result of the run will be output in gray and gray Code