存在继承关系的java对象初始化顺序
- 执行父类静态域和静态初始化块。
- 执行子类静态域和静态初始化块。
- 执行父类非静态的实例域和实例初始化块。
- 执行父类的构造器方法。
- 执行子类非静态的实例域和实例初始化块。
- 执行子类的构造器方法。
示例
public class ObjectInitializeOrder { public static void main(String[] args) throws Exception { new SonClass(); }}class FatherClass { private static final Logger LOGGER = LoggerFactory.getLogger(FatherClass.class.getSimpleName()); // 实例属性fatherInstanceVariable和instance block中的instanceBlockInitial()是相同优先级的,看代码顺序 public int fatherInstanceVariable = fatherInstanceVariableInitial(); public static int fatherStaticVariable = fatherStaticVariableInitial(); { instanceBlockInitial(); } // 这里static的fatherStaticVariable和staticBlockInitial()要看代码顺序,哪个在前就先招待哪个,优先级相同 static { staticBlockInitial(); } public FatherClass() { LOGGER.info("4. FatherClass Constructor invoked by : {}", this.getClass().getSimpleName()); } public int fatherInstanceVariableInitial() { LOGGER.info("3. father public instance variable initialized in {} and by : {}", FatherClass.class.getSimpleName(), this.getClass().getSimpleName()); return 0; } public static int fatherStaticVariableInitial() { LOGGER.info("1. father public static variable initialized in : {}", FatherClass.class.getSimpleName()); return 1; } public void instanceBlockInitial() { LOGGER.info("3. father instance block initialized in {} and by : {}", FatherClass.class.getSimpleName(), this.getClass().getSimpleName()); } public static void staticBlockInitial() { LOGGER.info("1. father static block initialized in : {}", FatherClass.class.getSimpleName()); }}class SonClass extends FatherClass { private static final Logger LOGGER = LoggerFactory.getLogger(SonClass.class.getSimpleName()); public int sonInstanceVariable = sonInstanceVariableInitial(); public static int sonStaticVariable = sonStaticVariableInitial(); { sonInstanceBlockInitial(); } static { sonStaticBlockInitial(); } public SonClass() { LOGGER.info("6. SonClass Constructor invoked by : {}", this.getClass().getSimpleName()); } public int sonInstanceVariableInitial() { LOGGER.info("5. son public instance variable initialized in : {}", this.getClass().getSimpleName()); return 0; } public static int sonStaticVariableInitial() { LOGGER.info("2. son public static variable initialized in : {}", SonClass.class.getSimpleName()); return 1; } public void sonInstanceBlockInitial() { LOGGER.info("5. son instance block initialized in : {}", this.getClass().getSimpleName()); } public static void sonStaticBlockInitial() { LOGGER.info("2. son static block initialized in : {}", SonClass.class.getSimpleName()); }} |
运行结果
1. father public static int initialized in : FatherClass
1. father static block initialized in : FatherClass
2. son public static int initialized in : SonClass
2. son static block initialized in : SonClass
3. father public int initialized in FatherClass and by : SonClass
3. father instance block initialized in FatherClass and by : SonClass
4. FatherClass Constructor invoked by : SonClass
5. son public int initialized in : SonClass
5. son instance block initialized in : SonClass
6. SonClass Constructor invoked by : SonClass
对象初始化的几点说明
- 类的每个基本类型数据成员(包括static成员)都会有一个默认初始值,对象的话为特殊值null。
- 无论创建多少个对象,相同类的静态数据都只占用一份存储区域。
- 静态域和静态块初始化只在Class对象首次加载的时候进行一次。
- 虽然没有显示地使用static关键字,构造器实际上也是静态方法。
- 实例初始化块是在构造器之前执行的。
- 创建类的第一个对象,或者是类的static域和方法被访问时,会触发类加载。
- 如果加载的类有基类,则会加载基类。
- 基类的构造器会被自动调用。