summary: mentions class loading many times, and you can't always recall the sequence immediately. This article will use an example to clarify many problems of class loading at one time.

This article is shared from the HUAWEI CLOUD community " with 1 example plus 5 questions, to figure out the class loading problem in java at one time [Run! JAVA] ", original author: breakDraw.

Many times when it comes to class loading, you can't recall the sequence immediately. This article will use an example to clarify many problems of class loading at one time.

Loading order of Java classes

Quote a classic example on the Internet, and make a little change, so that everyone can better understand.

The original example is quoted from: https://blog.csdn.net/zfx2013/article/details/89453482

public class Animal {
    private int i = test();
    private static int j  = method();
    static {
        System.out.println("a");
    }
    Animal(){
        System.out.println("b");
    }
    {
        System.out.println("c");
    }
    public int test(){
        System.out.println("d");
        return 1;
    }
    public static int method(){
        System.out.println("e");
        return 1;
    }
}
public class Dog extends Animal{
    {
        System.out.println("h");
    }
    private int i = test();
    static {
        System.out.println("f");
    }
    private static int j  = method();

    Dog(){
        System.out.println("g");
    }
    public int test(){
        System.out.println("i");
        return 1;
    }
    public static int method(){
        System.out.println("j");
        return 1;
    }
    public static void main(String[] args) {
        Dog dog = new Dog();
        System.out.println();
        Dog dog1 = new Dog();
    }
}

What will be output when this main program is executed?
the answer is
eafjicbhig
icbhig

In order to make it easier for everyone to understand each of the details, I will ask questions in another way.
Q: When will the assignment of static variables and the execution of static code blocks be carried out?
A:

  • Create an instance of a certain class or a subclass of a certain class for the first time
  • Access the static variables of the class and call the static methods of the class
  • Use reflection method forName
  • Call the main method of the main class (the first static initialization of this example actually belongs to this situation, and the main method of Dog is called)
    Note: The class initialization will only be performed once, after any of the above conditions are triggered, the class initialization operation will not be caused afterwards.

Q: When initializing a subclass, will the parent class be statically initialized? What's the order?
A: If the parent class has not been statically initialized before, it will proceed, and the order is from the parent class to the child class. The same goes for the subsequent initialization of non-static members.
So it will output eafj first.

Q: Why is the method of the parent class not overwritten by the method of the subclass?
A: Static methods are class methods and will not be overridden by subclasses. After all, when a class method is called, it must be accompanied by the class name.

Q: Why is the first output e instead of a?
A: Because the display assignment code of the class variable and the static code block code are executed in order from top to bottom.
During the static initialization of Animal, the method is called before the static code block, so first output e and then output a.
In the static initialization process of Dog, the method is called after the static code block, so f is output first, and then j is output.

Q: When super() is not called in the constructor of the subclass, will the parent class object be instantiated?
A: Yes. The default constructor of the parent class is automatically called. super() is mainly used when the special constructor of the parent class needs to be called.
Therefore, the Animal object will be instantiated first, and then the Dog object will be instantiated

Q: What is the order of construction method, member display assignment, non-static code block (that is, the two sentences that output c and h)?
A:

  1. Member display assignment, non-static code block (in the order of definition)
  2. Construction method
    Therefore, the instantiation process of Animal outputs icb (if you have any questions about output i, see the following question)
    Then instantiate Dog and output hig

Q: Why does i=test() output i instead of d when Animal is instantiated?
A: Because you really created the Dog subclass, the test() method in the Dog subclass has the same signature as the superclass test method, so the test method has been overridden.
At this time, even if it is called in the parent class, the method of using the child class Dog is still used. Unless your new is Animal.

Q: Same as the previous question. If the test methods are all private or final attributes, will the situation of the previous question change? ?
A:
Because private and final methods cannot be overridden by subclasses.
So when Animal is instantiated, i=test outputs d.

summarize the order:

  1. Explicit assignment of parent class static variables, parent class static code block (in the order of definition)
  2. Explicit assignment of subclass static variables, subclass static code block (in the order of definition)
  3. Explicit assignment of non-static variables of the parent class (instance member variables of the parent class), non-static code blocks of the parent class (in the order of definition)
  4. Parent class constructor
  5. Subclass non-static variables (subclass instance member variables), subclass non-static code blocks (in the order of definition)
  6. Subclass constructor.

Class loading process

Q: The three necessary stages of class loading are:
A:

  1. Loading (the class loader reads the binary byte stream and generates java class objects)
  2. Link (verify, assign initial zero value for static domain)
  3. Initialization (the previous topic actually talked about the order of initialization)
    More details are as follows:
    image.png

The relationship between passive reference and class static initialization

Q: When an array of a certain class is new, will class initialization be triggered?
What is output like below

public class Test {
    static class A{
        public static int a = 1;
        static{
            System.out.println("initA");
        }
    }
 
    public static void main(String[] args) {
        A[] as = new A[5];
    }

}
A:
When the array is new, the class initialization will not be triggered.
Nothing is output.

Q: Will referencing the final static field of a class trigger class initialization?
What does it output like below?

public class Test {
    static class A{
        public static final int a = 1;
        static{
            System.out.println("initA");
        }
    }

    public static void main(String[] args) {
        System.out.println("A.a=" + A.a);
    }
}

A: It won't be triggered.
Will not output initA. Remove the final will trigger.
(Note that this must be a basic type constant, if it is a reference type output, it will trigger class initialization)

Q: The subclass refers to the static members of the parent class. Will the subclass perform class initialization at this time?
What will be output as follows

public class Test {
    static class A{
        public static int a = 1;
        static{
            System.out.println("initA");
        }
    }

    static class B extends A{
        static {
            System.out.println("initB");
        }
    }

    public static void main(String[] args) {
        System.out.println("B.a=" + B.a);
    }
}

A:
The subclass will not be initialized.
Print initA, but not initB.

Class loader

Parental delegation

Parent delegation model when class loading, I don't know how to ask questions. . . Anyway, remember to go to the parent class loader first to see if the class can be loaded.

Just post a picture:
image.png

Note that there is a problem with the picture above.
Bootsrap is not a subclass of ClassLoader, it is written in C++.
And ExtClassLoader and AppClassLoader are inherited from ClassLoader

Q: In Java, if the package name and name of the class and interface are the same, then they must be the same class or interface?
A: Wrong.
In a JVM, the uniqueness of classes and interfaces is determined by the binary name and its defined class loader .
Therefore, when two different loaders load the same class or interface, they are actually different.

Click to follow, and learn about the fresh technology of Huawei Cloud for the first time~


华为云开发者联盟
1.4k 声望1.8k 粉丝

生于云,长于云,让开发者成为决定性力量