代码块
静态代码块
关注
- 先有语句输出,后打印,说明先执行代码块,后执行构造器
- 静态代码块在创建类对象时执行,且每创建一次则执行一次
- 一定是先执行代码块,后执行构造器
关注属性赋值顺序:
非静态代码块与显式初始化按顺序结构执行
非静态代码块总结
- 初始化块(初始化属性)
- 在创建类对象时执行,且每创建一次则执行一次
- 创建对象–》加载实例变量到内存中–》执行代码块,进行初始化
- 代码块与显式初始化顺序结构执行
- 先执行非静态代码块,后执行构造器
静态代码块
- 静态的属性或方法只加载一次,同理,静态代码块只加载一次
- 加载早于非静态,早于构造器
- 创建对象之前加载类,则类的静态结构均加载,
然后创建对象时,加载实例变量和一般方法
静态代码块不能调用非静态变量或方法(同static关键字章节内容)
代码块总结
-
调用顺序:
第一梯队:静态代码块(同梯队之间顺序结构)静态属性
第二梯队:非静态代码块,显式初始化(同梯队间顺序结构)
第三梯队:构造器 -
调用规则
非静态结构可调用静态结构,也可调用非静态结构
静态结构只能调用静态结构 -
内存结构
静态代码块只加载一次,随类加载而加载
非静态代码块随对象加载而加载
代码块练习
判断输出结果
class Root{
static{
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public 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 TestLeaf{
public static void main(String[] args){
new Leaf();
//new Leaf();
}
}
创建leaf对象《–调用构造器《–加载当前类(静态结构)《–加载父类的静态结构
静态结构加载完毕,开始加载非静态,非静态中先非静态代码块,再构造器
执行结果1
执行结果2(new Leaf()注释取消)
静态代码块只执行一次