今天为了搞清楚实例化一个对象时其属性等的实例化顺序,写了下面的例子来探究:
实例化一个C的对象,其中,A为其静态属性,B为其普通属性;D为C的父类,E为D的静态属性,F为D的普通属性;C中还包含了静态代码块和普通代码块。
package com.yawn;
public class Test3 {
public static void main(String[] args) {
System.out.println("-------第1次实例化-------");
new C();
System.out.println("-------第2次实例化-------");
new C();
}
}
class A {
public A(){
System.out.println("构造静态属性A");
}
}
class B {
public B(){
System.out.println("构造普通属性B");
}
}
class E {
public E(){
System.out.println("父类的静态属性E");
}
}
class F {
public F(){
System.out.println("父类的普通属性F");
}
}
class D {
static E e = new E();
F f = new F();
public D(){
System.out.println("构造父类D");
}
}
class C extends D{
/**
* 静态代码块先于构造器执行 普通块先于构造块 只执行一次
* 凡是静态的与对象无关,先于对象存在的; 凡是静态的都是共享的
*/
B b = new B();
static A a = new A();
{
System.out.println("普通代码块");
}
static {
System.out.println("静态代码块");
}
public C(){
System.out.println("构造函数C");
}
}
运行结果:
-------第1次实例化------- 父类的静态属性E 构造静态属性A 静态代码块 父类的普通属性F 构造父类D 构造普通属性B 普通代码块 构造函数C -------第2次实例化------- 父类的普通属性F 构造父类D 构造普通属性B 普通代码块 构造函数C
结论(实例化顺序):
静态的东西只在第一次实例化的时候执行
原则:先静态后非静态、先父类后子类