Go: "Deep Java Virtual Machine" Three: class initialization

Source: Internet
Author: User
Tags array definition

Reprint Please specify source: http://blog.csdn.net/ns_code/article/details/17845821

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 four cases in which the class must be initialized immediately:

    • When you encounter the four bytecode directives of new, getstatic, putstatic, Invokestatic, if the class has not yet been initialized, you need 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.
    • When you use the Java.lang.refect package method to make a reflection call to a class, you need to trigger its initialization first if the class has not yet been initialized.
    • 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.
    • 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 virtual machine specifies that only these four cases will trigger the initialization of the class, known as 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

[Java]View plain copy
  1. Class father{
  2. public static int m = 33;
  3. static{
  4. System.out.println ("parent class is initialized");
  5. }
  6. }
  7. Class child extends father{
  8. static{
  9. System.out.println ("subclass is initialized");
  10. }
  11. }
  12. Public class statictest{
  13. public static void Main (string[] args) {
  14. System.out.println (CHILD.M);
  15. }
  16. }

The results of the output after execution are as follows:

The parent class is initialized
33

For a static field, only the class that directly defines the field is initialized, so referencing a 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.

2. 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

[Java]View plain copy
  1. Class const{
  2. public static final String NAME = "I am constant";
  3. static{
  4. SYSTEM.OUT.PRINTLN ("Initialize const class");
  5. }
  6. }
  7. Public class finaltest{
  8. public static void Main (string[] args) {
  9. System.out.println (Const.name);
  10. }
  11. }

The results of the output after execution are as follows:

I'm a constant.

Although the Const class's constant name is referenced in the program, the value of this constant, I am constant, is stored in the constant pool of the class finaltest called it, and the reference to the constant const.name is actually converted to the Finaltest class's reference to its constant pool in the compile phase. In other words, there is actually no symbolic reference entry for the Const class in the Finaltest class file, and there is no connection to the two classes after they are translated into class files.

3. Referencing a class by an array definition does not trigger initialization of the class

[Java]View plain copy
  1. Class const{
  2. static{
  3. SYSTEM.OUT.PRINTLN ("Initialize const class");
  4. }
  5. }
  6. Public class arraytest{
  7. public static void Main (string[] args) {
  8. Const[] con = new const[5];
  9. }
  10. }

does not output any information after execution, stating that the Const class is not initialized.

However, this code triggers the initialization of another class named "Llconst", which is a virtual machine generated automatically, Directly inherits from the subclass of the Java.lang.Object, the creation action is triggered by the bytecode directive NewArray, and it is clear that this is an initial initialization of an array reference type, and that the element in the array contains only a reference to the Const class and does not initialize it. If we add instantiation code to each of the Const class elements in the con array, the initialization of the Const class is triggered, as follows:

[Java]View plain copy
  1. Class const{
  2. static{
  3. SYSTEM.OUT.PRINTLN ("Initialize const class");
  4. }
  5. }
  6. Public class arraytest{
  7. public static void Main (string[] args) {
  8. Const[] con = new const[5];
  9. For (Const A:con)
  10. A = new Const ();
  11. }
  12. }

This will result in the following output:

Initialize the Const class
According to the first article of the four rule, the new here triggers the Const class.

Finally, the initialization of the interface differs from the class initialization process.

The interface also has the initialization process, the above code we all use static statement block to output initialization information, and in the interface cannot use "static{}" statement block, but the compiler will still generate the <clinit> class constructor for the interface, Used to initialize a member variable defined in an interface, which is actually a global constant of the static final adornment.

The main difference between the two is that when a class initializes, it requires that its parent be initialized, but when an interface is initialized, it does not require that its parent interface be initialized, and the parent interface is initialized only when the parent interface is actually used, such as a constant defined in the reference interface. This is also very different from class initialization, and looking back at the 2nd example, we know that the initialization of the class is not triggered when the static final constant in the call class is invoked, but the initialization of the interface is triggered when the static final constant in the calling interface is invoked.

Go: "Deep Java Virtual Machine" Three: class initialization

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.