From one instance to see Java class loading mechanism

One example

Today, such a code in the study:

public class debug{

	// b 的定义
	Thread b;
	public debug(){
		Thread a=new Thread(new Runnable(){
			int count=0;
			public void run() {
				while(true) {
					count++;
					System.out.println("a进程");
					try {
						Thread.sleep(2000);
						System.out.println("222");

						// b的使用,调用其join方法,使其他线程等待b执行完再执行
						b.join();
						System.out.println("333");
					}catch(Exception e) {
						e.printStackTrace();
					}
					if(count==5) {
						break;
					}
				}
			}
		});
		a.start();

		//b的初始化
		b=new MyThread();
		b.start();
		System.out.println("主进程");
	}
	public static void main(String[] args) {
		new debug();
	}
	
	class MyThread extends Thread{
		public MyThread() {
			System.out.println(111);
		}
	}
}

Look at my top three lines of comments, from order point of view, the code looks like this thread b of the life cycle is the definition of first use, then initialize the stands to reason that is being given, but the above code is not the problem, its output as follows:

111
主进程
a进程
222
333
a进程
222
333
a进程
222
333
a进程
222
333
a进程
222
333

Note the print statement 111and 222row, 111row b is to mark the thread initialization time, and 222the line is marked b the use of time, so, it seems Code Execution of order to it, I study something in depth, it is found Java class loading mechanism of the stymied *** ***

Java class loading mechanism

Java classes begin to be loaded into the virtual machine memory, to unload a far memory, its entire life cycle, including: Load (Loading), verification (Verification), preparation (Preparation), analytical (Resolution), initializing (Initialization), use (using) and unloading (unloading) seven stages. Wherein preparation, verification, referred to as analytical part 3 connected (Linking)

Here we focus only ready, parsing, initialization phase to phase

Preparation (Preparation)

Preparation phase is formally allocate memory for class variables (static member variables) and set the class variable initial value (zero value) of the stage, the memory used by these variables are allocated in the method area. This time includes only the memory allocation class variables, instance variables without including instance variables will be assigned together with the object when the object is instantiated in the heap. Secondly, the "normally" referred to here is the initial value of the data type of zero value, assuming a class variable is defined as:

public static int value = 123;

Then, after the variable value in the preparation phase value of 0 instead of 123. Because this time has not yet started any java method, and the value assigned to putstatic instruction 123 after the program is compiled, stored in a class constructor method () in, so the value assigned to the action will take 123 during the initialization phase carried out. As for the "special case" means: when the class attribute field is ConstantValue field, initialized to the specified value, then it is marked as a final, value of the value in the preparation stage 123 is initialized to 0 instead of in the preparation phase.

public static final int value = 123;

Parsing (Resolution)

Parsing stage is a virtual machine to a constant pool of symbolic references to the process of replacing direct references. The main analysis operation for the class or interface, fields, methods class, interface method, type method, and calls the method handle 7 points class qualifiers for symbolic references.

Initialization (Initialization)

Class initialization phase is the final step class loading process. In front of the class load, by addition to defining class loader from participation, the remaining operation is completely dominated by the virtual machine in the loading phase and the user application control. To the initialization phase, really started java class defined in the program code (bytecode).

During the preparation phase variables that have been assigned through the system requirements of the initial value (zero value) once; while in the initialization phase, to initialize class variables and other resources based on subjective Scheduler ape through a program developed or, more bluntly: <font size = 6, color = "red"> initialization phase is performed during the class constructor () method. () Method is implemented by the assignment operation compiler automatically collected class all class variables and static statement block static statements merger of {}, the order compiler collection was in order of appearance by the statement in the source file of the decision static statements can only access the block to define variables before the static block of statements, as defined in the variable after it, in front of a static blocks can be assigned, but can not be accessed. as follows:

public class Test{
	static{
    	i=0;
    	System.out.println(i);//Error:Cannot reference a field before it is defined(非法向前引用)
	}
	static int i=1;
}

So the comment the line of code error, and into the following situations, the program can compile and be a normal operation.

public class Test{
	static{
    	i=0;
    	//System.out.println(i);
	}

	static int i=1;

	public static void main(String args[]){
    	System.out.println(i);
	}
}/* Output:	1

Class constructor () and instance constructors () different, it does not require the programmer to explicitly call, the virtual guarantee prior to execution, the parent class constructor () is finished in a subclass of the class constructor (). Because the constructor of the parent class () first implementation, the static initialization statement block means that the parent class defined in the / static variables to give priority to the static initialization statement block subclass / static variables execution. In particular, the class constructor () for a class or interface is not essential, if a class is not a static block of statements, there is no assignment of class variables, the compiler may not produce for the class class constructor ( ).

Java object creation

Look above the red word very excited, that has been resolved, but said above is the class static variable, and the program is an instance variable. In fact, the above procedure is based on the principle:

<Font size = 6, color = "red"> Example instance variables initialization block initializes always occurs before the constructor initializes

Sample code:

public class debug{
	// b 的定义
	Thread b;

	public debug(){
		
		// 构造函数  fourth
		Thread a=new Thread(new Runnable(){
			int count=0;
			public void run() {
				while(true) {
					count++;
					System.out.println("a进程");
					try {
						Thread.sleep(2000);
						System.out.println("222");
						// b的使用,调用其join方法,使其他线程等待b执行完再执行
						b.join();
						System.out.println("333");
					}catch(Exception e) {
						e.printStackTrace();
					}
					if(count==5) {
						break;
					}
				}
			}
		});
		a.start();
		//b的初始化           third
		b=new MyThread();
		b.start();
		System.out.println("主进程");
	}
	
	//实例代码块             second
	{
	System.out.println(1.5);
	}
	//静态代码块             first
	static {
		System.out.println(0.5);
	}
	
	public static void main(String[] args) {
		new debug();
	}
	
	class MyThread extends Thread{
		public MyThread() {
			System.out.println(111);
		}
	}
}

Sample output:

0.5
1.5
111
a进程
主进程
222
333
a进程
222
333
a进程
222
333
a进程
222
333
a进程
222
333

I have come to

When the execution order of the code in a new instance of a class: static block of code> example block> instance variable is initialized (because static variables in the class loading time is initialized, then the initialization process of initialization statements also collected, and the initialization statements the specific location is not so much (except static / example code blocks and constructors) it causes artifacts above)> constructor.

Published 84 original articles · won praise 250 · Views 150,000 +

Guess you like

Origin blog.csdn.net/ygdxt/article/details/88143030