一、代码块和构造函数的初始化顺序
先从实例代码开始
父类
public class SuperClass {
static {
System.out.println("super static block init");
}
{
System.out.println("no static block init");
}
public SuperClass() {
System.out.println("super Instance");
}
子类
public class SubClass extends SuperClass {
static {
System.out.println("sub static block init");
}
{
System.out.println("sub no static block init");
}
public SubClass() {
System.out.println("sub Instance");
}
}
下面这行代码的数据结果是什么?
SuperClass superClass = new SuperClass();
输出结果
super static block init
no static block init
super Instance
总结:针对单个类,初始化顺序:静态代码块,非静态代码块,构造函数
下面的这行代码又会输出怎么样的结果?
SubClass subClass = new SubClass();
输出结果
super static block init
sub static block init
no static block init
super Instance
sub no static block init
sub Instance
子类实例化时,输出的顺序如下:
父类的静态代码块->子类的静态代码块->父类的非静态代码块->父类的构造函数->子类的非静态代码块->子类的构造函数
二、代用静态方法和静态变量
下面的示例代码分析
父类
public class SuperClass {
static {
System.out.println("super static block init");
}
{
System.out.println("no static block init");
}
public SuperClass() {
System.out.println("super Instance");
}
public static void superTest() {
System.out.println("super method");
}
public static final Integer countInteger = 123;
public static final int countInt = 345;
}
子类
public class SubClass extends SuperClass {
static {
System.out.println("sub static block init");
}
{
System.out.println("sub no static block init");
}
public SubClass() {
System.out.println("sub Instance");
}
public static void sub() {
System.out.println("sub method");
}
public static final String hello = "hello";
public static final int testInt = 3;
public static final Integer testInteger = 4;
}
观察输出结果:
System.out.println(SuperClass.countInt);
//345
********************
System.out.println(SuperClass.countInteger);
// super static block init
// 123
********************
System.out.println(SubClass.countInteger);
// super static block init
// 123
********************
System.out.println(SubClass.countInt);
// 345
********************
SuperClass.superTest();
// super static block init
// super method
********************
SubClass.superTest();
// super static block init
// super method
********************
System.out.println(SubClass.testInt);
// 3
********************
System.out.println(SubClass.testInteger);
// super static block init
// sub static block init
// 4
********************
System.out.println(SubClass.hello);
// hello
********************
SubClass.sub();
// super static block init
// sub static block init
// sub method
********************
SubClass[] subClasses = new SubClass[2];//无任何内容输出
总结
- 子类调用父类的静态字段或者静态方法,只会触发父类的初始化;
- 父类调用父类的静态方法,会触发父类的静态块初始化;
- 子类调用子类的静态方法,会触发父类的静态块和子类的静态块的初始化;
- 关于Int,string 和Integer输出结果的不同,是由于Int和string类型在编译阶段jvm放到了常量池中。
本文详细解析了Java中类的初始化流程,包括静态代码块、非静态代码块及构造函数的执行顺序,并通过实例展示了子类如何继承父类的初始化过程。此外,还探讨了静态方法和静态变量的初始化时机及其在继承中的表现。
340

被折叠的 条评论
为什么被折叠?



