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()