本文主要介紹JAVA中執行順序 以及 JAVA中賦值順序
一、JAVA中執行順序
第一部分很好測試,我們只需要寫一個子類,類中定義一個靜態塊,一個普通塊,一個構造器,它的父類構造器,都打印一條語句,即可明白它們直接的執行順序
Mastiff類
- /**
- * 子類藏獒
- */
- public class Mastiff extends Dog {
- public Mastiff() {
- System.out.println("Mastiff");
- }
- {
- System.out.println("block");
- }
- static {
- System.out.println("static block");
- }
- public static void main(String[] args){
- Mastiff mastiff=new Mastiff();
- }
- }
DOG類
- /**
- *DOG父類
- */
- public class Dog {
- public Dog() {
- System.out.println("Dog");
- }
- }
運行結果爲:
static block Dog block Mastiff |
也就是說,在我們的程序中,實例化一個類對象的時候,運行順序爲:
靜態塊 父類構造器 本類中的塊 本類的構造器
我們可以更進一步,如果在父類中也有塊和靜態塊呢?
DOG類改進後源碼
- /**
- *DOG父類
- */
- public class Dog {
- public Dog() {
- System.out.println("Dog");
- }
- static{
- System.out.println("super static block");
- }
- {
- System.out.println("super block");
- }
- }
Mastiff改進後源碼
- /**
- * 子類藏獒
- */
- public class Mastiff extends Dog {
- public Mastiff() {
- System.out.println("Mastiff");
- }
- {
- System.out.println("block");
- }
- static {
- System.out.println("static block");
- }
- public static void main(String[] args){
- Mastiff mastiff=new Mastiff();
- }
- }
運行的結果爲:
super static block static block super block Dog block Mastiff |
也就是說此時的運行順序爲:
- 父類靜態塊
- 自身靜態塊
- 父類塊
- 父類構造器
- 自身塊
- 自身構造器
好了,知道了運行的順序,那麼這是爲什麼呢?這就要從JVM中類的裝載機制和實例化機制開始說起,這裏因爲主題原因,先不討論,有興趣的同學可以自己查資料。
二、JAVA中賦值順序
我們再來討論第二個問題,一個變量的值,它有可能在哪些地方確定呢??
從父類繼承該值(包括:1.作爲父類的成員變量已經賦值 2.在父類的塊中賦值 3.在父類的構造器中賦值)在構造器中對其進行賦值在塊中進行賦值在方法調用中進行賦值
現在假設在我們剛剛的例子中,有一個變量type,表示狗的品種
- /**
- *DOG父類
- */
- public class Dog {
- public String type="父類成員變量賦的值";
- public Dog() {
- System.out.println("父類構造器--type-->"+type);
- type="父類構造器賦的值";
- System.out.println("父類構造器----type--->"+type);
- }
- {
- System.out.println("block---type--->"+type);
- type="父類塊賦的值";
- }
- }
- /**
- * 子類藏獒
- */
- public class Mastiff extends Dog {
- public String type="成員變量賦的值";
- public Mastiff() {
- System.out.println("構造器---type--->"+type);
- type="構造器賦的值";
- }
- public void say(){
- System.out.println("say---type---->"+type);
- }
- {
- System.out.println("block---type--->"+type);
- type="塊賦的值";
- }
- public static void main(String[] args){
- Mastiff mastiff=new Mastiff();
- mastiff.say()</span><span style="font-size: medium;">;</span><span style="font-size: medium;">
- }
- }
執行結果如下:
block---type--->父類成員變量賦的值 父類構造器--type-->父類塊賦的值 父類構造器----type--->父類構造器賦的值 block---type--->成員變量賦的值 構造器---type--->塊賦的值 say---type---->構造器賦的值 |
答案很明顯,賦值順序爲:
- 父類成員變量賦值
- 父類塊賦值
- 父類構造器賦值
- 自身成員變量賦值
- 自身塊賦值
- 自身構造器賦值
結合我們前面說的程序中的執行順序,這個顯然是很好理解的:
1.成員變量賦值>>>塊賦值>>>構造器賦值
2.父類的塊>>父類構造器>>自身塊>>自身構造器
又因爲一個成員變量是不可能在靜態變量中賦值的,而且又前面程序執行順序可知
靜態塊>>塊
所以,程序的賦值步驟爲
- 父類的靜態變量賦值
- 自身的靜態變量賦值
- 父類成員變量賦值
- 父類塊賦值
- 父類構造器賦值
- 自身成員變量賦值
- 自身塊賦值
- 自身構造器賦值