在Java程序中,我们是可以在构造方法中调用本类的方法和成员变量的,但是要注意一点,当我们需要调用一个非static的方法时,该方法不应该可以被子类覆盖,应该用final修饰或将其变成private,这虽然语法上没有具体要求,但是若不遵守这个约定,会导致异常情况发生。
具体原因我们看以下测试代码:
Father.java
public class Father {
public void invokeInConstructor(){
System.out.println("调用了父类中的invokeInConstructor方法");
}
public Father(){
System.out.println("父类构造方法");
this.invokeInConstructor();
}
}
Son.java
public class Son extends Father {
//普通成员变量初始化的时间在调用父类构造方法之后,调用子类构造方法之前。
private Date date = new Date();
//子类覆盖了父类的方法,并且在其中调用了子类的成员变量
@Override
public void invokeInConstructor(){
System.out.println("在子类中已经初始化了的date对象:" + date);
}
public Son(){
super();
}
//使用main函数测试
public static void main(String[] args) {
System.out.println("==========构造父类==========");
Father father = new Father();//构造父类
System.out.println("==========构造子类==========");
Son son = new Son();
}
}
执行结果:
可以看到,当我们在构造子类时,会先调用父类的构造方法,而父类的构造方法中调用的是invokeInConstructor,该方法在子类中被覆盖,因为多态特性,父类构造器实际上调用的是子类的invokeInConstructor方法,而该方法中调用了在执行父类构造器时还未来得及初始化成员变量(该成员变量会在子类构造器调用之前执行),这会导致抛出空指针异常等等后果。