1. 程式人生 > >Java類的各種成員初始化順序如:父子類繼承時的靜態代碼塊,普通代碼塊,靜態方法,構造方法,等先後順

Java類的各種成員初始化順序如:父子類繼承時的靜態代碼塊,普通代碼塊,靜態方法,構造方法,等先後順

依次 成員初始化順序 main class 實例對象 變量 影響 {} 所在

class B extends A ,然後A類也就是父類裏面有靜態代碼塊,普通代碼塊,靜態方法,靜態成員變量,普通成員變量,普通方法。
子類也是這樣,然後繼承之後,關於程序打印輸出的結果。
涉及到Java類的各種成員的初始化順序。
經測試,得到如下結論:

1.父類【靜態成員】和【靜態代碼塊】,按在代碼中出現的順序依次執行。
2.子類【靜態成員】和【靜態代碼塊】,按在代碼中出現的順序依次執行。
3.父類的【普通成員變量被普通成員方法賦值】和【普通代碼塊】,按在代碼中出現的順序依次執行。
4.執行父類的構造方法。
5.子類的【普通成員變量被普通成員方法賦值】和【普通代碼塊】,按在代碼中出現的順序依次執行。
6.執行子類的構造方法。


下面看測試代碼以及測試結果的圖:

父類:

package com.lxk.ClassInitTest;/** * 父類 * <p> * Created by lxk on 2017/4/20 */public class Parent {static {System.out.println("父類:靜態代碼塊");}{System.out.println("父類:普通代碼塊");}private static String staticStringInParent = initStaticStringInParent();private String stringInParent = initStringInParent();public Parent() {System.out.println("父類:構造方法");}private static String initStaticStringInParent() {System.out.println("父類:靜態方法,被靜態成員變量賦值調用。");return "initStaticStringInParent";}private String initStringInParent() {System.out.println("父類:普通成員方法,被普通成員變量賦值調用。");return "initStringInParent";}}

子類:

package com.lxk.ClassInitTest;/** * 子類 * <p> * Created by lxk on 2017/4/20 */public class Child extends Parent {private String stringInChild = initStringInChild();private static String staticStringInChild = initStaticStringInChild();{System.out.println("子類:普通代碼塊");}static {System.out.println("子類:靜態代碼塊");}public Child() {System.out.println("子類:構造方法");}private static String initStaticStringInChild() {System.out.println("子類:靜態方法,被靜態成員變量賦值調用。");return "initStaticStringInChild";}private String initStringInChild() {System.out.println("子類:普通成員方法,被普通成員變量賦值調用。");return "initStringInChild";}}

測試main方法

package com.lxk.ClassInitTest;/** * 測試Java類的成員和初始化塊(代碼塊)初始化順序 * <p> * Created by lxk on 2017/4/20 */public class ClassInitTest {public static void main(String[] args) {System.out.println("測試代碼開始");new Child();System.out.println("測試代碼結束");}}


代碼的執行結果圖:

為了看的方便,我把代碼執行結果,和得到的理論放在一個圖。

技術分享圖片


分析:

我在子類裏面,調換了代碼的 順序,父類和子類的順序是不一樣的,看的時候註意,

這個也是測試結論的一環。

(2018.01.23 更新)

上面的描述有問題,

{System.out.println("父類:構造代碼塊");}

這東西,應該叫,構造代碼塊,構造 code block,不是我上面寫的

下面再多科普一下吧
普通代碼塊:
方法或語句中出現的{}就稱為普通代碼塊。
普通代碼塊和一般的語句執行順序由他們在代碼中出現的次序決定--“先出現先執行”
靜態代碼塊:
在java中使用static關鍵字聲明的代碼塊。
靜態塊用於初始化類,為類的屬性初始化。每個靜態代碼塊只會執行一次。
由於JVM在加載類時會執行靜態代碼塊,所以靜態代碼塊先於主方法執行。
如果類中包含多個靜態代碼塊,那麽將按照"先定義的代碼先執行,後定義的代碼後執行"。
註意:
1 靜態代碼塊不能存在於任何方法體內。
2 靜態代碼塊不能直接訪問靜態實例變量和實例方法,需要通過類的實例對象來訪問。
構造代碼塊:
直接在類中定義且沒有加static關鍵字的代碼塊稱為{}構造代碼塊
構造代碼塊在創建對象時被調用,每次創建對象都會被調用,並且構造代碼塊的執行次序優先於類構造函數
這個構造代碼塊的執行順序不會因為方法所在位置而影響,我特意將他放在構造函數之後。



Java類的各種成員初始化順序如:父子類繼承時的靜態代碼塊,普通代碼塊,靜態方法,構造方法,等先後順