[Reprinted] Java series notes (1), reprinted java series notes
Java series notes (1)-Java class loading and initialization
Address: http://www.cnblogs.com/zhguang/p/3154584.html
Directory
Class Loader
Before learning about the Java mechanism, you must first understand how classes are loaded in the JVM (java Virtual Machine). This will play an important role in understanding other Java mechanisms.
Each Class is compiled to generate a Class Object stored in. in the class file, JVM uses the Class Loader to load the class bytecode file (. class), the class loader is essentially a class Loader chain. Generally, we only use a native class loader, which only loads trusted classes such as Java APIs, generally, it is only loaded in a local disk. These classes are generally enough for us to use. If we need to download the. class bytecode file from a remote network or database, we need to mount an additional class loader.
Generally, the class loader is organized according to the hierarchy of the tree. Each loader has a parent class loader. In addition, each class loader supports the proxy mode, that is, you can complete Java class loading by yourself, or you can delegate to other class loaders.
There are two types of class loaders: parent class priority policy and self-priority policy, the parent class priority policy is General (for example, JDK adopts this method). In this policy, before a class loads a Java class, will try to delegate to the parent class loader. Only when the parent class loader cannot be found will you try to load it yourself. The preferred policy is opposite to that of the parent class. It first tries to load the parent class before loading the parent class loader when it cannot be found, which is used in web containers (such as tomcat).
Dynamic Loading
No matter what kind of class loaders or classes are used, they are dynamically loaded to the JVM when they are used for the first time. This sentence has two meanings:
The differences between loading and initialization need to be distinguished. loading a class. Class file does not mean that the class object is initialized. In fact, initialization of a Class includes three steps:
- Loading is executed by the Class loader to find the bytecode and create a Class Object (only create );
- Link (Linking), verify the bytecode, allocate storage space for the static domain (only the allocation, not the initialization of the bucket), and parse the applications required to create the class for other classes;
- Initialize the static Initialization block, initialize static variables, and execute static methods (such as constructor ).
Link
After the Java class is loaded, the link is required. Simply put, the link combines the loaded java binary code into the JVM running state. It consists of three steps:
Initialization
Note: In Java programming ideology, the static {} clause is executed and executed for the first time when the class is loaded. It may be a written mistake or a translation error, because the example in this book shows that static is executed at the first initialization.) in Java deep adventure, static {} is executed and executed at the first instantiation, both of these two types should be incorrect. static {} is executed at the first initialization and only once. The following code can be used to determine whether:
Package myblog. classloader;/*** @ project MyBlog * @ create June 18, 2013 7:00:45 * @ version 1.0.0 * @ author Zhang Guang */public class Toy {private String name; public static final int price = 10; static {System. out. println ("Initializing");} Toy () {System. out. println ("Building");} Toy (String name) {this. setName (name);} public static String playToy (String player) {String msg = buildMsg (player); System. out. println (msg); return msg;} private String buildMsg (String player) {String msg = player + "plays" + name; return msg ;}// the class above, run the following code: Class c = Class. forName ("myblog. rtti. toy "); // c. newInstance ();
We can see that, without instantiation, the static {} clause will still be executed only when the forName Initialization is executed, but the constructor will not be executed. Therefore, only Initializing and no Building are output.
For initialization, @ achun axiao provides detailed scenarios in the comments in this article. Thanks @ achun axiao:
According to the java Virtual Machine specification, all java virtual machines must be implemented for the first time by java programs in each class or interface.Active use.
There are 6 types of active use:
1) create a class instance
2) access the static variable of a class or interface, or assign a value to the static variable (if you access the static compilation constant (that is, the constant that can be determined during compilation), it will not cause class initialization)
3) Call static methods of Classes
4) Reflection (Class. forName (xxx. xxx. xxx ))
5) initialize a subclass of A Class (equivalent to active use of the parent class), but directly referencing the parent class element through the subclass will not cause initialization of the subclass (see example 6)
6) classes marked as startup classes (including main methods) for Java virtual machines)
The class is different from the interface initialization. If a class is initialized, its parent class or parent interface will also be initialized. However, if an interface is initialized, it will not cause initialization of its parent interface.
Example
1. Through the above explanation, we can understand the following program (the following program is partly from Java programming ideas):
Class Toy {static {System. out. println ("Initializing"); // static clause, which is executed only once when the class is loaded and initialized for the first time, and only once} Toy () {System. out. println ("Building"); // constructor, loaded every time a new object is declared }}
In the preceding program segment, when Class. forName ("Toy") is called for the first time, the static clause is executed. If new Toy () is executed later, only the constructor is executed.
2. Note thatNewInstance ()Method
Class cc = Class. forName ("Toy"); // obtain the class (note that you need to use a fully qualified name containing the package name) Toy toy = (Toy) cc. newInstance (); // It is equivalent to a new object, but the Gum class must have a default constructor (No parameter)
3. UseClass literal constantBoth. class and Class. forName can create an application for the class, but the difference is that when you use Gum. Class to create an application for the class object,Not Automatically initializedThis Class Object (the static clause will not be executed)
Public class TestToy {public static void main (String [] args) {// try {// Class c = Class. forName ("myblog. classloader. toy "); //} catch (ClassNotFoundException e) {// e. printStackTrace (); //} Class c = Toy. class; // no value is output }}
Use Toy. the class is executed during the compilation period, so the Toy must already exist during the compilation. class file, otherwise the compilation will fail, which is consistent with the Class. forName ("myblog. classloader. toy ") different, the latter is dynamic loading during runtime.
However, if the main method is directly written in the Toy class, call Toy. class, which will cause initialization and output Initializing. The reason is not Toy. class, but the class contains the main startup method, which will lead to Toy initialization.
4,Compilation frequency. Return to the complete Toy class. If the output is: System. out. println (Toy. price), the static clause and constructor are not executed, because in Toy, the constant price is limited by static final.Compilation frequencyFor such constants, they can be read without initialization.
The compile time must meet three conditions: static, final, and constant.
The following are not compilation times. class initialization will occur for their applications:
static int a;final int b;static final int c= ClassInitialization.rand.nextInt(100);static final int d;static { d=5;}
5,The essence of static Blocks. Note the following code:
class StaticBlock { static final int c = 3; static final int d; static int e = 5; static { d = 5; e = 10; System.out.println("Initializing"); } StaticBlock() { System.out.println("Building"); }}public class StaticBlockTest { public static void main(String[] args) { System.out.println(StaticBlock.c); System.out.println(StaticBlock.d); System.out.println(StaticBlock.e); }}
What is the output of this code? Initialing output before c, d, and e, or after? Is e output 5 or 10?
Run the following command and the result is:
3
Initializing
5
10
The answer is 3: first output, Intializing and later output, and e outputs 10. Why?
The reason is: when c is output, because c is a frequent compilation volume and does not cause class initialization, It is output directly. When d is output, d is not a frequent compilation volume, therefore, Initialization is triggered, that is, the execution of the static block. Therefore, d is assigned 5, e is assigned 10, Initializing is output, and d is 5 and e is 10.
But why is e 10? Originally, JDK will automatically create a static block for e initialization (refer to: http://www.java3z.com/cwbwebhome/article/article8/81101.html? Id = 2497), so the above Code is equivalent:
class StaticBlock { static final int d; static int e; static { e=5; } static { d = 5; e = 10; System.out.println("Initializing"); } StaticBlock() { System.out.println("Building"); }}
Visible,Executed in sequenceE is initialized to 5 first, and then initialized to 10, so 10 is output.
Similarly, it is easy to think of the following code:
class StaticBlock { static { d = 5; e = 10; System.out.println("Initializing"); } static final int d; static int e = 5; StaticBlock() { System.out.println("Building"); }}
In this Code, the declaration of e is placed behind the static block. Therefore, e is first initialized to 10 and then initialized to 5. Therefore, e is output to 5 in this Code.
6. When accessing a static domain of a Java class or interface, only the classes or interfaces that actually declare this domain will be initialized (Java deep adventure).
/*** Example from Chapter 2 of Java deep adventure * @ author Zhang Guang **/class B {static int value = 100; static {System. out. println ("Class B is initialized"); // output} class A extends B {static {System. out. println ("Class A is initialized"); // No output} public class SuperClassTest {public static void main (String [] args) {System. out. println (. value); // output 100 }}
In this example, although the value is referenced through A, the value is declared in the parent class B, so it only initializes B without causing initialization of.
Description
During the development process, I found that my foundation was too weak. In addition to studying the basic syntax and usage of Java, I learned a little simple data structure and design patterns, there is no further in-depth study of the system, and the study at work is also a shot of the East and the West, not solid enough and the system. Think of a learning method:What you learned can be systematically expressed, indicating that you learned it.Therefore, I decided to learn and write and express what I learned in the form of a blog.
This document will be continuously updated due to deep learning or incorrect revisions.
Java notes are my notes on Java application and learning.Knowledge PointThe objective of writing this series of notes isLearningBecause I have learned how to write, the level is limited, there must be omissions in this article, welcome to the axe.
Many reference predecessors of books and blogs in this article, in principle will not reference the original, but to add their own understanding of the transformation, if there is reference, will indicate the source, if you have any questions, please contact: daniel.zhguang@gmail.com
Update record
June 25, 2013: published;
June 26, 2013: added @ achun axiao's comment: 6 initialization scenarios;
April June 28, 2013: Add link and initialization content. Add Example 6.
References in this section
JAVA programming ideology, Chapter 2
Java deep adventure
The essence of static blocks in Java: http://www.java3z.com/cwbwebhome/article/article8/81101.html? Id = 2497
Java class Loading, Linking, and Initialization: http://blog.csdn.net/biaobiaoqi/article/details/6909141