- 类成员初始化执行顺序
代码示例:
class Father {
static{
System. out.println("父类静态代码块初始化" );//1
}
{
System. out.println("父类代码块初始化" );//4
}
private static String s=print();
public static String print()
{
System. out.println("父类静态方法" );//2
return "父类静态成员变量的初始化" ;
}
public Father()
{
System. out.println("父类无参构造函数初始化完成" );//5
show();
}
public void show()
{
System. out.println("父类show()方法" );//6多态原因执行子类的
} } class Son extends Father{
static{
System. out.println("子类静态代码块初始化" );//3
}
{
System. out.println("子类代码块初始化" );//7
}
private static int i=1;
private String s="子类私有成员变量" ;
public void show()
{
System. out.println("子类show()方法:i=" +i);//9
}
public Son()
{
System. out.println("子类构造函数初始化完成" );//8
show();
} }
public class test {
public static void main(String[] args)
{
new Son();
} }
运行结果:
父类静态代码块初始化
父类静态方法
子类静态代码块初始化
父类代码块初始化
父类无参构造函数初始化完成
子类show()方法:i=1
子类代码块初始化
子类构造函数初始化完成
子类show()方法:i=1
从结果可以看出类中各成员初始化的顺序是:
1.如果类中存在继承关系(像 Son 继承 Father) 则首先会初始化子类(Son)的父类(Father),然后再是子类
2.在父类首先会初始化静态 的东西 静态块>静态变量 而且只初始化一次 (因为静态的东西都是跟着类的加载而加载的)
3.随后就是初始化子类的静态东西 跟父类的静态初始化一样(同上)
4.初始化父类无参构造器(调用有参就初始化有参构造器)
5.初始化子类无参构造器(注意:子类的成员变量和代码块都是是比构造函数的初始化要早。。看输出结果可知)
如果去掉子类中 private static int i=1;变量的static关键字,则输出结果变为:
父类静态代码块初始化
父类静态方法
子类静态代码块初始化
父类代码块初始化
父类无参构造函数初始化完成
子类show()方法:i=0
子类代码块初始化
子类构造函数初始化完成
子类show()方法:i=1
可以看出将子类中的静态成员变量i 变成了成员变量i,可以看出结果是截然不同,现在的结果是:0
原因:因为上面的静态成员变量是跟着类的加载而初始化的,所以结果是1,而下面的成员变量又因为现在还在父类构造器中所以子类中的成员变量还没有得到初始化所以是 0
所以上面的初始化顺序不够完整,现在补全下:
首先jvm加载类时 会对每个对象的默认初始化为 0,对通过组合方式的引用类型默认初始化为 null
总结:
java中首先初始化父类再初始化子类(有多少个父类初始化多少个)
- 变量初始化顺序
代码示例:
class Person{
private int no;
private String name;
private boolean isStudent;
static{
}
{
System.out.print("代码块执行前:");
show();//1
no=12;
name="张三";
isStudent=true;
}
public void show()
{
System. out.println("no=" + no + ", name=" + name + ", isStudent=" + isStudent);
}
public Person()
{
System.out.print("构造函数执行前:");
show();//2
this.no=11;
this.name="asd";
this.isStudent=true;
}
}
public class test {
public static void main(String[] args) {
Person p = new Person();
System.out.print("实例化后调用show():");
p.show();//3
}
}
运行效果:
代码块执行前:no=0, name=null, isStudent=false
构造函数执行前:no=12, name=张三, isStudent=true
实例化后调用show():no=11, name=asd, isStudent=true
在new一个对象时,所有属性声明没有初始化值,在程序编译期间,会默认赋值null(String类型为null,int类型是0)。