final修饰符和初始化块
用{}包括起来,执行顺序在构造方法之前;
多个初始化块一起就是按照从上到下的顺序执行;
static修饰的初始化块叫静态初始化块,又叫类初始化块
就是在初始化块前面加上一个static;
在父类中:
//final修饰符和初始化块
public class FinalDemo {
// final什么的变量要指定初始值
// final修饰的实例变量一般以大写和下划线_搭配命名
final int NUM_A;
final int NUM_B = 2;// 在声明的时候指定初始值
final int NUM_C;
static final String STR_1;
static final String STR_2 = "字符串2";
{
// 在初始化块中指定初始值
NUM_A = 1;
System.out.println("父类初始化块语句1");
System.out.println("父类初始化块语句2");
}
public FinalDemo() {// 构造器
// 在构造器中指定初始值
NUM_C = 3;
System.out.println("父类构造器语句1");
System.out.println("父类构造器语句2");
}
static {
// 在静态初始化块中指定初始值
STR_1 = "字符串1";
System.out.println("父类静态初始化语句1");
System.out.println("父类静态初始化语句2");
}
//final修饰的方法不能被子类重写
public final void finalFunction(){
System.out.println("final修饰的方法");
}
//final修饰的类不能被继承,也不能被子类重写
public final class FinalClass{
String a="final修饰的类";
}
public static void main(String[] args) {
FinalDemo finaldemo = new FinalDemo();
System.out.println(finaldemo.NUM_A);
System.out.println(finaldemo.NUM_B);
System.out.println(finaldemo.NUM_C);
System.out.println(finaldemo.STR_1);
System.out.println(finaldemo.STR_2);
}
}
/*由此可见,静态初始化的执行顺序在初始化块前面,初始化块的执行顺序在构造器前面
即:执行顺序:静态初始化块>初始化块>构造器
静态初始化块又叫类初始化块,在类加载的时候就加载了,
所以静态初始化块只会在第一次调用该类的时候才会执行,
第二次调用该类的时候由于该类已经存在在内存中了,不需要再加载,
因此不执行静态初始化块(在单个类中);
(在多个继承中的类),优先执行所有静态初始化块,再执行初始化块、构造器;
*/
子类继承后:
public class FinalDemoOne extends FinalDemo {
{
System.out.println("子类初始化块1");
System.out.println("子类初始化块2");
}
static {
System.out.println("子类静态初始化块1");
System.out.println("子类静态初始化块2");
}
public FinalDemoOne() {
System.out.println("子类构造器1");
System.out.println("子类构造器2");
}
public static void main(String[] args) {
FinalDemoOne finaldemoone = new FinalDemoOne();
System.out.println("----第二次创建对象时----");
FinalDemoOne finaldemotwo = new FinalDemoOne();
}
}
/*
在继承中,先执行父类的静态初始化块,再执行子类的静态初始化块;
再是父类的初始化块、构造器,子类的初始化块、构造器;
第二次创建对象时,由于该类已经存在在内存中,父类的静态初始化块不再执行,
所以是父类初始化块、构造器,子类初始化块、构造器;
*/
结果图展示: