示例代码如下:
/*类的初始化顺序及继承顺序
*
* */
class One {
public static String S = "父类-静态变量";
public String S1 = "父类-常规变量";
static { System.out.println("父类-静态初始化块"); }
{ System.out.println("父类-初始化块"); }
public One() {System.out.println("父类-默认构造函数");}
public One(int a) { System.out.println("父类-有参构造函数"); }
protected void printA() { System.out.println("父类-保护方法A"); }
private void printB() { System.out.println("父类-私有方法B"); }
protected void printAB()
{
printA();
printB();
}
}
public class Two extends One
{
public static String ts = "子类-静态变量";
String ts2 = "子类-常规变量";
static
{
// System.out.println(ts2); 在静态代码块中进行非静态引用会报错
System.out.println("子类-静态初始化块");
}
{
System.out.println("子类-初始化块");
}
public Two() { System.out.println("子类-默认构造函数"); }
public Two(int a) { System.out.println("子类-有参构造函数"); }
protected void printA() {System.out.println("子类-保护方法A");}
@SuppressWarnings("unused")
private void printB() {System.out.println("子类-私有方法B");}
public static void main(String[] args)
{
System.out.println("==================父类对象引用父类实例==========================");
One o = new One(2);
o.printAB();
System.out.println("==================父类对象引用子类实例==========================");
One t = new Two(2);
t.printAB();
System.out.println("==================子类对象引用父类实例==========================");
//Two two = new One(2); 报错 子类对象不能引用父类实例
//t.printAB();
System.out.println("==================子类对象引用子类实例==========================");
Two two = new Two(2);
two.printAB();
System.out.println("==================子类对象引用子类实例-无参情况下==========================");
Two two2 = new Two();
}
}
***********************运行结果***********************
父类-静态初始化块
子类-静态初始化块
==================父类对象引用父类实例==========================
父类-初始化块
父类-有参构造函数
父类-保护方法A
父类-私有方法B
==================父类对象引用子类实例==========================
父类-初始化块
父类-默认构造函数
子类-初始化块
子类-有参构造函数
子类-保护方法A
父类-私有方法B
==================子类对象引用父类实例==========================
==================子类对象引用子类实例==========================
父类-初始化块
父类-默认构造函数
子类-初始化块
子类-有参构造函数
子类-保护方法A
父类-私有方法B
==================子类对象引用子类实例-无参情况下==========================
父类-初始化块
父类-默认构造函数
子类-初始化块
子类-默认构造函数
总结:由结果可以看出,静态初始化块会在类加载的时候执行(即在类构造之前),非静态初始化块会在构造对象时自动执行。
无论是父类对象引用子类实例还是子类对象引用子类实例,运行结果都是一样的,所以主要还是取决于实例属于父类还是子类。
子类实例在初始化的时候会自动调用默认构造函数,至于自己的构造函数的调用由初始化的时候参数设置选择相应的构造函数。