Abstract: Many times when it comes to class loading, you can’t immediately recall the order. This article will use an example to clarify the problems of class loading once and for all.
This article is from The huawei cloud community “Use 1 example and 5 problems to solve the class loading problem in Java”.
Most of the time when it comes to class loading, you can’t immediately recall the order. This article will use an example to clarify the many problems of class loading once and for all.
The loading order of Java classes
Cite a classic example from the Internet, and modify it slightly for better understanding.
The original examples cited from: blog.csdn.net/zfx2013/art…
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(); }}Copy the code
If I execute this main program, what does it say?
The answer is eafjicbhigicbhig
To make it easier for you to understand the details, LET me ask the question in a different way.
Q: When are static variables assigned and static code blocks executed?
A:
-
Creates an instance of a class or a subclass of a class for the first time
-
Access a class’s static variables and call a class’s static methods
-
Use the reflection method forName
-
Call the main method of the main class (the first static initialization in this example was actually in this case, using the main method of Dog). Note: Class initialization occurs only once, and after any of the above conditions are triggered, no further class initialization is caused.
Q: When initializing a subclass, does the parent class get statically initialized as well? The order?
A: If the parent class has not been statically initialized before, then it will be initialized in the order that the parent class is subclassed. The same is true for subsequent non-static member initialization. So eAFJ is printed first.
Q: Why can’t methods of a parent class be overridden by methods of a subclass?
A: Static methods are class methods and cannot be overridden by subclasses. After all, class methods are always called with the class name.
Q: Why is the first output e instead of A?
A: Because the display assignment code and static code block code for class variables are executed from top to bottom. Animal static initialization method is called before the static block, so print a and e first. In Dog’s static initialization, method is called after the static block, so f is printed first, then j
Q: Are superclass objects instantiated when super() is not called in the constructor of the subclass?
A: Yes. The default constructor for the parent class is automatically called. Super () is primarily used when special constructors of the parent class need to be called. So you instantiate Animal first, and then you instantiate Dog
Q: What is the order of constructor, member display assignment, non-static code block (i.e., the two sentences that output C and H)?
A:
1. Members display assigned, non-static code blocks (in defined order)
So the instantiation of Animal outputs ICb (if in doubt about output I, see below) and then the instantiation of Dog outputs HIg
Q: Why is I =test() printed in Animal instantiation instead of d?
A: Because what you are really creating is A Dog subclass, the test() method in the Dog subclass is overridden because its signature is the same as the test method in its parent class. At this point, even if called in the parent class, the method using the subclass Dog is still used. Unless you’re new to Animal.
Q: Same as above, if test methods are private or final, will the situation change?
A: Because private and final methods cannot be overridden by subclasses. So when Animal is instantiated, I =test prints d.
To summarize the order:
1. Explicit assignment of superclass static variables, superclass static code blocks (in defined order)
2. Subclass static variable explicit assignment, subclass static code block (in order defined)
3. Explicit assignment of superclass non-static variables (superclass instance member variables), superclass non-static code blocks (in defined order)
4. Superclass constructor
5. Subclass non-static variables (subclass instance member variables), subclass non-static code blocks (in order defined)
6. Subclass constructor.
Class loading process
Q: The three phases of class loading are:
A:
1. Load (the class loader reads the binary byte stream and generates Java class objects)
2. Link (validate, assign static field initial zero value)
3. Initialize (the previous topic is actually the order of initialization)
Passive reference versus class static initialization
Q: Does new an array of a class cause class initialization? Like what is output 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]; }}Copy the code
A: Class initialization is not raised when an array is new.
Output nothing.
Q: Does referring to a final static field of a class cause class initialization? Like what is output 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); }}Copy the code
A: No.
InitA will not be printed. Removing final will raise. (Note that this must be a primitive type constant; if it is a reference type yield, class initialization will be triggered.)
Q: If a subclass refers to a static member of its parent class, does it do class initialization? What is output below
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); }}Copy the code
A: Subclasses are not initialized.
InitA is printed, but initB is not.
Class loader
Parents delegate
Parent delegate model for class loading. Anyway, remember to go to the parent class loader first to see if the class loads.
Just post a picture
Note that there is something wrong with the picture above.
Bootsrap is not a ClassLoader subclass, it is written in C++.
ExtClassLoader and AppClassLoader both inherit from ClassLoader
Q: In Java, do class and interface packages have the same package name and name, so it must be the same class or interface?
A: Wrong. The uniqueness of a class and interface in a JVM is determined by the binary name and its defining classloader. So when two different loaders load the same class or interface, they are actually different.
Click to follow, the first time to learn about Huawei cloud fresh technology ~