面試問題是寫出下面程序的輸出,答案爲null。java
public class Base { private String baseName = "base"; public Base() { callName(); } public void callName() { System.out.println(baseName); } static class Sub extends Base { private String baseName = "sub"; public void callName() { System.out.println(baseName); } public static void main(String[] args) { Base b = new Sub(); } } }
這段代碼中類的初始化順序是這樣的,父類靜態塊 ->子類靜態塊->父類構造器(屬性在構造器中初始化) -> 子類構造器 。面試
摘抄一段靠譜評論:jvm
看我大師歸來:
1. Base b = new Sub();
2. Base b = 直接忽略,從 new Sub();開始
3. 類加載器加載 Base,Sub 類到jvm;
4. 爲Base,Sub 類中的兩個屬性baseName 分配存儲空間,可是不初始化;
注意:屬性的初始化是放在構造器中,按照代碼順序執行的。
5. new Sub會調用Sub的無參構造器,而在這個構造器中會隱式調用父類Base的無參構造器;
6. 父類Base的構造器中代碼本質是
public Base()
{
baseName = "base";
callName();
}
即父類的屬性baseName 的值爲base。但爲什麼輸出null,騷年別急。
7. 由於父類構造器方法是在子類中調用的,即大環境是子類,此時this指向Sub。此時,調用的方法callName()固然是指子類的方法。而這個方法打印的屬性baseName固然也是子類的。那如今子類的屬性baseName的值是多少呢?答案是null.由於此時子類Sub的構造器內代碼本質是:
super();
baseName="sub";
此時baseName="sub"還沒執行。this
所以,最後的值固然是null.spa