java类成员初始化顺序:


属性、方法、构造方法和自由块都是类中的成员,在创建类的对象时,类中各成员的执行顺序:


1.父类静态成员和静态代码快,按在代码中出现的顺序依次执行。


2.子类静态成员和静态代码块,按在代码中出现的顺序依次执行。


3. 父类的实例成员和实例代码块,按在代码中出现的顺序依次执行。


4.执行父类的构造方法。


5.子类实例成员和实例代码块,按在代码中出现的顺序依次执行。


6.执行子类的构造方法。


package javainthink.chapter57;

public class TestDemo {
	
	public static void main(String[] args) {
		Son son = new Son();
	}
}

class Window{
	Window(String str){
		System.out.println(str+"初始化");
	}
}

class Parent{
	public static Window window1= new Window("window1");
	
	public Window window2 = new Window("window2");
	
	public Parent(){
		System.out.println("parant构造方法被调用");
	}
	
	{
		System.out.println("parant非静态代码块被调用");
	}
	
	static {
		System.out.println("parant静态代码块被调用");
	}
}

class Son extends Parent{
	
	public static Window window1= new Window("window3");
	
	public Window window2 = new Window("window4");
	
	public Son() {
		System.out.println("son构造方法被调用");
	}
	
	{
		System.out.println("son非静态代码块被调用");
	}
	
	static {
		System.out.println("son静态代码块被调用");
	}
}
运行结果:
window1初始化
parant静态代码块被调用
window3初始化
son静态代码块被调用
window2初始化
parant非静态代码块被调用
parant构造方法被调用
window4初始化
son非静态代码块被调用
son构造方法被调用


代码块:



是指用{}包起来的代码,java中的代码按其所在位置可分为四种代码块:


1.  构造代码块:


位置:处于类成员位置,也就是上个例子的非静态代码块位置处。


主要用于对象的初始化操作,在创建对象时调用,可以用于完成初始化属性值、加载其他的类的功能。




2. 静态代码块:


位置:位于类成员位置。


作用:初始化块主要用于初始化静态变量和静态方法,静态初始化块只调用一次,是在类的第一次加载到内存时,并非一定要创建对象才执行。


3. 局部代码块:


位置:位于方法内。


作用: 限定代码块中的变量的生命周期,在代码快结束后就可以释放。


同步代码块


位置:位于方法内


作用:控制线程安全


在线程调用该方法时,被调用。


public class TestDemo {
	{
		//构造代码块
	}
	
	static {
		//静态代码块
	}
	
	public void demo() {
		{
			//局部代码快
		}
	}
	
	public void demo2(Object obj){
		synchronized(obj){
		    // 需要同步执行的代码
		}
	}
	
}

对象初始化时执行顺序: 静态代码块 > 构造代码块 > 构造方法







静态代码块和非静态代码块的区别?


非静态代码块主要是用于对象的初始化操作,在每次创建对象的时都要调用一次,其执行顺序在构造方法之前。


在非静态代码块之前加static修饰,则为静态代码块。由于非静态成员不能再静态方法中使用,同样也不能在静态代码块中,因此,静态代码块主要用于初始化静态变量和静态方法,静态代码块只调用一次,是在类的第一次加载到内存时,并非一定要创建对象才执行,


静态代码块比非静态代码块先执行。



构造器的初始化:

在类的内部,变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法定义之间,他们仍旧会在任何方法(包括构造器)被调用之前得到初始化。(java编程思想94页)

class Window {
  Window(int marker) { print("Window(" + marker + ")"); }
}

class House {
  Window w1 = new Window(1); // Before constructor
  House() {
    // Show that we're in the constructor:
    print("House()");
    w3 = new Window(33); // Reinitialize w3
  }
  Window w2 = new Window(2); // After constructor
  void f() { print("f()"); }
  Window w3 = new Window(3); // At end
}

public class OrderOfInitialization {
  public static void main(String[] args) {
    House h = new House();
    h.f(); // Shows that construction is done
  }
}
输出结果:
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()