《尚硅谷》课程上有关代码块的分析
class Root{
static{
System.out.println("Root的静态初始化块");
}
public Root(){
System.out.println("Root的无参数的构造器");
}
{
System.out.println("Root的普通初始化块"); //虽然写在构造器之后,但输出在构造器之前
}
}
class Mid extends Root{
static{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid(){
System.out.println("Mid的无参数的构造器");
}
public Mid(String msg){
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数构造器,其参数值:"
+ msg);
}
}
class Leaf extends Mid{
static{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf(){
//通过super调用父类中有一个字符串参数的构造器
super("尚硅谷");
System.out.println("Leaf的构造器");
}
}
public class LeafTest{
public static void main(String[] args){
new Leaf();
System.out.println("**********************");
new Leaf(); //第二次创建对象将不再执行静态初始化
}
}
输出结果如下:
Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:尚硅谷
Leaf的普通初始化块
Leaf的构造器
**********************
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:尚硅谷
Leaf的普通初始化块
Leaf的构造器
.
-
以static声明的静态代码块随着类的加载而执行,且只执行一次。静态代码块按照从父类到子类的加载顺序依次执行,因此看到结果中先执行Root→Mid→Leaf的静态代码块。
-
.而非静态代码块随着对象的创建而执行,每创建一个对象就执行一次非静态代码块,可以看到代码中创建了两个对象,因此有两组重复的输出,但第二个对象并没有执行静态代码块,因为类只加载了一次。
-
在Root类可以看到特意将构造器写在非静态代码块之前,但输出结果显示还是Root的非静态代码块先执行,因此可以认为,创建对象之时,非静态代码块执行在类的构造器之前。