最近刷面试题发现关于java 中new对象时构造函数,构造代码块等的调用顺序是常考点,下面的一些总结:
请看下面的demo程序:
public class Father {
public static Variable a=new Variable();
public Variable b=new Variable(1);
static{
System.out.println("父类静态代码块1");
}
static{
System.out.println("父类静态代码块2");
}
{
System.out.println("父类构造代码块1");
}
{
System.out.println("父类构造代码块2");
}
public Father(){
System.out.println("父类构造函数");
}
}
public class Sun extends Father {
public static Variable c=new Variable();
public Variable d=new Variable(1);
static{
System.out.println("子类静态构造代码块1");
}
static{
System.out.println("子类静态构造代码块2");
}
{
System.out.println("子类构造代码块1");
}
{
System.out.println("子类构造代码块2");
}
public Sun(){
System.out.println("子类构造函数");
}
}
public class Variable {
public Variable(){
System.out.println("静态变量初始化");
}
public Variable(int i){
System.out.println("一般变量初始化");
}
}
public class Main {
public static void main(String[] args) {
Sun s=new Sun();
}
}
以下是输出:
静态变量初始化
父类静态代码块1
父类静态代码块2
静态变量初始化
子类静态构造代码块1
子类静态构造代码块2
一般变量初始化
父类构造代码块1
父类构造代码块2
父类构造函数
一般变量初始化
子类构造代码块1
子类构造代码块2
子类构造函数
另外这里再说一个易于搞混的地方:我们知道子类和父类之间的方法覆盖,如果子类对象赋值给父类引用,在调用覆盖的方法时会调用子类的方法,这是所谓的动态绑定。但对于变量而言是不存在动态绑定的,当子类与父类有相同名字的变量时,如果子类对象赋值给父类引用,那么变量的值是等于父类的变量的值而不是子类。
public class Father {
public static int static_a=1000;
public int notStatic_b=20000;
}
public class Sun extends Father {
public static int static_a=10;
public int notStatic_b=20;
}
public class Main {
public static void main(String[] args) {
Sun s=new Sun();
Father f=s;
System.out.println(s.static_a+" "+s.notstatic_b);
System.out.println(f.static_a+" "+f.notstatic_b);
}
}
结果是:
10 20
1000 20000