可見java基礎還是很重要的,我相信還是有很多人寫錯的,貼出來大家一起學習。
題目要求:輸出運行結果:
- public class Text {
- public static int k =0 ;
- public static Text t1 = new Text("t1") ;
- public static Text t2 = new Text("t2") ;
- public static int i = print("i") ;
- public static int n =99 ;
- public int j = print("j") ;
- {
- print("構造塊");
- }
- static {
- print("靜態塊");
- }
- public Text(String str){
- System.out.println((++k)+":"+str+" i="+i+" n="+n) ;
- ++i;++n ;
- }
- public static int print(String str){
- System.out.println((++k)+":"+str+" i="+i+" n="+n) ;
- ++n;
- return ++i ;
- }
- public static void main (String args[]){
- Text t = new Text("init") ;
- }
- }
運行結果如下:
1:j i=0 n=0 2:構造塊 i=1 n=1 3:t1 i=2 n=2 4:j i=3 n=3 5:構造塊 i=4 n=4 6:t2 i=5 n=5 7:i i=6 n=6 8:靜態塊 i=7 n=99 9:j i=8 n=100 10:構造塊 i=9 n=101 11:init i=10 n=102
|
首先看到static關鍵字,腦子裏面第一反應有幾點,
1、公有屬性,可以有類名稱直接訪問。
2、靜態方法,可以有類名稱直接方法。
3、靜態方法或者屬性,可以再對象實例化之前就調用
至於該題中,順序執行,先執行public static int k =0 ;
因爲沒有輸出不用考慮這個,接着public static Text t1 = new Text("t1") ;
在t1對象初始化時先執行非靜態方法或者非靜態常量,順序執行,接着運行構造參數,
根據程序來看應該打印三條記錄,分別是
1:j i=0 n=0 2:構造塊 i=1 n=1 3:t1 i=2 n=2 |
接下來public static Text t2 = new Text("t2") ;同理,執行完之後繼續執行static代碼塊或者賦值靜態變量,在main()方法中new了一個新的實例,靜態變量只執行一次,接下來就是順序執行非靜態方法---->構造方法。應該是這樣的順序,面試的時候我寫的不完成,哎。
接着想到繼承關係(extends)子類繼承一個父類之後,對象初始化的順序又是怎樣?
我寫了一個demo,大家共勉
- class A{
- public static int k = 0 ;
- static {
- System.out.println("父類靜態方法") ;
- }
- {
- System.out.println("父類非靜態方法") ;
- }
- public A(){ //構造
- System.out.println("父類構造");
- }
- }
- class B extends A{
- static {
- System.out.println("子類靜態方法") ;
- }
- {
- System.out.println("子類非靜態方法") ;
- }
- public B(){ //構造
- System.out.println("子類構造");
- }
- }
- public class Demo {
- public static void main(String args[]){
- B b = new B() ;
- }
- }
輸入結果如下:
父類靜態方法 子類靜態方法 父類非靜態方法 父類構造 子類非靜態方法 子類構造 |
最後總結了幾點:
- 1 /*
- 2 * 幾大原則
- 3 * 一、靜態成員變量(Static)
- 4 * 1、靜態成員變量爲類變量,所有對象共享同一內存空間
- 5 * 2、靜態成員變量的聲明和定義僅在首次加載類時執行一次
- 6 * 3、首次加載類時首先對所有靜態成員變量根據類型默認賦初值,然後再對有右值的附右值
- 7 * 二、靜態初始塊
- 8 * 1、靜態初始化塊僅在首次加載類時執行一次
- 9 * ······多個靜態成員變量與靜態始化快參照出現順序先後執行······
- 10 * 三、動態成員變量
- 11 * 1、動態成員變量定義在每次實例化對象時在構造函數之前執行
- 12 * 四、動態初始化塊
- 13 * 1、動態初始化塊在每次實例化對象時在構造函數之前執行
- 14 * ······多個動態成員變量與動態初始化塊參照出現順序先後執行······
- 15 * 總結:總的來說,在不涉及繼承的前提下,當首次加載類時,按照如下順序執行
- 16 * 1、按照出現順序先後執行靜態成員變量定義與靜態初始化塊
- 17 * 2、按照出現順序先後執行動態成員變量定義與動態初始化塊
- 18 * 3、執行構造函數
- 19 * 再次實例化對象時只執行第2、3步即可
- 20 *
- 21 * ············成員變量與定義與初始化塊先於構造函數執行·········
- 22 * 五、當涉及到繼承時,按照如下順序執行
- 23 * 1、執行父類的靜態成員變量定義與靜態初始化塊,執行子類的靜態成員變量定義與靜態初始化塊
- 24 * 2、執行父類的非靜態成員變量定義與動態初始化塊,執行父類構造方法
- 25 * 3、執行子類的非靜態成員變量定義與動態初始化塊,執行子類構造方法
- 26 * 另:父類構造方法中用到的方法如果已被子類重寫,那麼在構造子類對象時在調用父類構造函數中使用子類重寫的方法
總結了一點,不對之處還望多多指點,多謝。
轉載地址:http://blog.csdn.net/cherishme1988/article/details/12095637