源**如下:
class father
public void init()
static
static
}class son extends father
}public class test
}
執行結果如下:
讓我們來分析下流程:
①.當主函式中 system.out.println(father.f); 這行**執行時,因為father類中的f是static final 修飾的並且是_顯式的賦值了_(後面講介紹沒有顯式的賦值)的常量(編譯時常量),所以呼叫列印father.f 只會列印該常量,並不會涉及到father類的載入(把father載入到記憶體),因此father中的靜態**塊不會被呼叫。
②.當執行father f = new son();這行**時,因為要new son();所以要載入son類進記憶體,以為son類還繼承了father類,要先把father類載入到記憶體,father內載入到記憶體後靜態第乙個靜態**快執行了,輸出 init,當執行到第二靜態**塊時,son類還沒有被載入進記憶體,因此列印son.f輸出為 null ,然後是son類被載入到記憶體,呼叫 son的預設構造器,然後再向上呼叫父類的預設構造器,別忘了此時可是this往上層級呼叫的,所以執行inin()方法,是son中的 init()方法,輸出 son init。
③.當執行system.out.println(f.f);該行**時。由於son類已經報給載入到記憶體了,**塊不會被執行,只會列印出 son 類中 f 的值 aa。
至此程式結束。
讓我們來修改下**,只修改一行:
public static string f = "aa";
執行結果如下:
讓我們來分析下流程:
①.當主函式中 system.out.println(father.f); 這行**執行時,此時 father 類被載入到記憶體,然後執行靜態**塊,執行第乙個靜態**塊,輸出 init ,執行第二個靜態**塊時,son 類被載入進記憶體,然後輸出 son 類中的 f 為son ,然後輸出 father 的 f 的值 aa。
②.當執行father f = new son();這行**時,此時 father 類 與 son 類都已經別載入到記憶體,然後執行 son 的預設構造器,再向上調運父類 father 的預設構造器,執行 init() 方法(注意此時的this),輸出 son init。
③.當執行system.out.println(f.f);該行**時。由於son類已經報給載入到記憶體了,**塊不會被執行,只會列印出 son 類中 f 的值 aa。
至此程式結束。
讓我們來修改下**,只修改一行:
public static final string f =string.valueof(new random().nextint(10));
執行結果如下:
讓我們來分析下流程:
執行結果與上邊第一次修改**時的結果一樣(執行順序一樣,相對應的步驟的值被修改的**替換掉了),這是為什麼呢?還記得沒有修改的原生面試題嗎?我們在執行的第一步中說,(編譯時常量:就這樣的:public static final string f = 「aa」;)(執行時常量呢:這樣的:public static final string f =string.valueof(new random().nextint(10));)看到區別了嗎?* 編譯時常量,如果用類名去呼叫時不會載入所在類的,而執行時常量是要載入所在類的。只用static修飾的變數在用 類名呼叫時也是需要載入所在類的。(原創個人觀點,目前就該題而言只能是通過輸出結果和個人斷點除錯等表象來得出結論,而不能從類的載入和呼叫機制來說明問題,問題先留這,等有了更深的理解,再來補充 ,歡迎各位給出建議和討論)
關於類名後加 符號時基類引用派生類的問題
關於類名後加 符號時基類引用派生類的問題 例如class cdata cdata fun cdata a,cdata b 這是引用。指標和引用的宣告方式 宣告指標 char pc 宣告引用 char c a char rc c 它們的區別 從現象上看,指標在執行時可以改變其所指向的值,而引用一旦和某...
類中的常量
類中的常量 有時我們希望某些常量只在類中有效。由於 define定義的巨集常量是全域性的,不能達到目的,於是想當然地覺得應該用const修飾資料成員來實現。const資料成員的確是存在的,但其含義卻不是我們所期望的。const資料成員只在某個物件生存期內是常量,而對於整個類而言卻是可變的,因為類可以...
類中的常量
類中的常量 2008年03月14日 星期五 上午 00 21 有時我們希望某些常量只在類中有效。由於 define 定義的巨集常量是全域性的,不能達到目的,於是想當然地覺得應該用const 修飾資料成員來實現。const 資料成員的確是存在的,但其含義卻不是我們所期望的。const 資料成員只在某個...