Java靜態和非靜態成員變數初始化過程解析
阿新 • • 發佈:2020-01-11
這篇文章主要介紹了Java靜態和非靜態成員變數初始化過程解析,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
Java中非靜態成員變數、靜態成員變數的初始化時機。
非靜態變數
我們在這裡分析三種結構,著重分析這三種結構的初始化順序:
- 成員變數初始化語句;
- 成員變數初始化塊;
- 建構函式;
示例一:
public class MyTest { private String name = "wei.hu"; public MyTest(String name) { System.out.println("This is constructor. Will assign the variable name to: " + name + "."); System.out.println("Before the name was modified: " + this.name); this.name = name; System.out.println("After the name was modified: " + this.name); } { System.out.println("This is initialize block. Will assign the variable name to: chouchou"); System.out.println("Before the name was modified: " + this.name); this.name = "chouchou"; System.out.println("After the name was modified: " + this.name); } public String getName() { return name; } public static void main(String[] args) { MyTest myTest = new MyTest("mengna"); System.out.println(myTest.getName()); } } #輸出 This is initialize block. Will assign the variable name to: chouchou Before the name was modified: wei.hu After the name was modified: chouchou This is constructor. Will assign the variable name to: mengna. Before the name was modified: chouchou After the name was modified: mengna mengna
示例二:
public class MyTest { public MyTest(String name) { System.out.println("This is constructor. Will assign the variable name to: " + name + "."); System.out.println("Before the name was modified: " + this.name); this.name = name; System.out.println("After the name was modified: " + this.name); } private String name = "wei.hu"; { System.out.println("This is initialize block. Will assign the variable name to: chouchou"); System.out.println("Before the name was modified: " + this.name); this.name = "chouchou"; System.out.println("After the name was modified: " + this.name); } public String getName() { return name; } public static void main(String[] args) { MyTest myTest = new MyTest("mengna"); System.out.println(myTest.getName()); } } #結果(與示例一相同) This is initialize block. Will assign the variable name to: chouchou Before the name was modified: wei.hu After the name was modified: chouchou This is constructor. Will assign the variable name to: mengna. Before the name was modified: chouchou After the name was modified: mengna mengna
示例三:
public class MyTest { public MyTest(String name) { System.out.println("This is constructor. Will assign the variable name to: " + name + "."); System.out.println("Before the name was modified: " + this.name); this.name = name; System.out.println("After the name was modified: " + this.name); } { System.out.println("This is initialize block. Will assign the variable name to: chouchou"); System.out.println("Before the name was modified: " + this.name); this.name = "chouchou"; System.out.println("After the name was modified: " + this.name); } private String name = "wei.hu"; public String getName() { return name; } public static void main(String[] args) { MyTest myTest = new MyTest("mengna"); System.out.println(myTest.getName()); } } #結果 This is initialize block. Will assign the variable name to: chouchou Before the name was modified: null After the name was modified: chouchou This is constructor. Will assign the variable name to: mengna. Before the name was modified: wei.hu After the name was modified: mengna mengna 分析: 注意本示例的結果與上面兩個示例的結果不同。 1、當我們想將成員變數name賦值為chouchou之前,發現this.name為null。也就是說初始化語句沒有先執行,而是先執行了初始化塊; 2、當在執行建構函式時,我們想將成員變數name賦值為mengna,發現賦值之前,this.name不再是chouchou,而是wei.hu,這說明了什麼? 因為初始化塊先執行,如果緊接著執行建構函式的話,那麼在建構函式賦值語句執行之前,this.name應該是chouchou才對。但是在建構函式賦值語句執行之前,this.name的值變成了wei.hu,那麼足以證明: 1)初始化塊先執行; 2)下來執行了初始化語句; 3)最後執行了建構函式;
結論:
通過上面三個示例,我們可以發現,對於非靜態的成員變數:
初始化語句、初始化塊,總是先於建構函式執行;
初始化語句、初始化塊的和執行順序,取決於 初始化語句、初始化塊在程式碼中的書寫順序。寫在上面的先執行。
靜態變數
我們在這裡也分析三種結構:
- 靜態初始化語句;
- 靜態初始化塊;
- 建構函式;
示例一:
public class MyTest { public static String name = "wei.hu"; public MyTest() { System.out.println("This is constructor. Will assign the variable name to: chouchou"); System.out.println("Before the name was modified: " + name); name = "chouchou"; System.out.println("After the name was modified: " + name); } static { System.out.println("This is static initialize block. Will assign the variable name to: mengna"); System.out.println("Before the name was modified: " + name); name = "mengna"; System.out.println("After the name was modified: " + name); } public static void main(String[] args) { System.out.println(MyTest.name); } } #結果 This is static initialize block. Will assign the variable name to: mengna Before the name was modified: wei.hu After the name was modified: mengna mengna 分析: 通過列印輸出,我們發現在執行靜態初始快之前,靜態變數name已經初始化為wei.hu了。也就是說: 1、靜態初始化語句先執行; 2、下來執行靜態初始化塊; 3、建構函式未執行; ---------------------
示例二:
public class MyTest { public MyTest() { System.out.println("This is constructor. Will assign the variable name to: chouchou"); System.out.println("Before the name was modified: " + MyTest.name); name = "chouchou"; System.out.println("After the name was modified: " + MyTest.name); } static { System.out.println("This is static initialize block. Will assign the variable name to: mengna"); System.out.println("Before the name was modified: " + MyTest.name); name = "mengna"; System.out.println("After the name was modified: " + MyTest.name); } public static String name = "wei.hu"; public static void main(String[] args) { System.out.println(MyTest.name); } } #結果 This is static initialize block. Will assign the variable name to: mengna Before the name was modified: null After the name was modified: mengna wei.hu 分析: 初始化塊在對靜態變數賦值之前,發現MyTest.name的值為空。 在最後打印出MyTest.name時,發現輸出的值是wei.hu,而不是mengna。也就是說,在初始化塊執行之後,執行了靜態初始化語句。 1、先執行靜態初始化塊; 2、再執行靜態初始化語句; 3、建構函式未執行; ---------------------
結論:
對於靜態欄位,初始化有如下規則:
1. 若靜態初始化語句在前,靜態程式碼塊在後,則先執行靜態初始化語句;
2. 若靜態程式碼塊在前,靜態初始化語句在後,則先執行靜態程式碼塊;
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。