Java基礎-代碼執行順序(重要)

來源:互聯網
上載者:User

標籤:類變數(靜態變數)、執行個體變數(非靜態變數)、靜態代碼塊、非靜態代碼塊


Java代碼初始化順序

    1.由 static 關鍵字修飾的(如:類變數[靜態變數]、靜態代碼塊)將在類被初始化建立執行個體對象之前被初始化,而且是按順序從上到下依次被執行。靜態(類變數、靜態代碼塊)屬於類本身,不依賴於類的執行個體。

    2.沒有 static 關鍵字修飾的(如:執行個體變數[非靜態變數]、非靜態代碼塊)初始化實際上是會被提取到類的構造器中被執行的,但是會比類構造器中的代碼塊優先執行到,非靜態(執行個體變數、非靜態代碼塊)的地位是相等的,它們將按順序被執行。


形參:

  1. 比如你定義一個函數void add(int a, int b),這裡的a和b就是形參。

  2. 當你進行函數調用的時候,add(1, 2),這裡的1和2就是實參。


向前引用:

所謂向前引用,就是在定義類、介面、方法、變數之前使用它們。


成員變數:
    在類體裡面定義的變數稱為成員變數;
    如果該成員變數有 static 關鍵字修飾,則該成員變數稱為 靜態變數類變數
    如果該成員變數沒有 static 關鍵字修飾,則該成員變數被稱為 非靜態變數執行個體變數

局部變數:
    形參、方法內定義的變數、代碼塊中定義的變數,都屬於局部變數。

類變數 (靜態變數
    1. 可以向前引用
    2. 變數屬於類本身
    3. 類變數不依賴類的執行個體,類變數只在初始化時候在方法區中被分配一次空間,無論類的執行個體被建立幾次,都不再為類變數分配空間
    4. 通過類的任意一個執行個體來訪問類變數,底層都將將其轉為通過類本身來訪問類變數,它們的效果是一樣的
    5. 一旦類變數的值被改變,通過類或類的任意一個執行個體來訪問類變數,得到的都將是被改變後的值
    6. 將在類的初始化之前初始化

執行個體變數(非靜態變數)
    1. 不能向前引用,如果向前引用,則稱為非法向前引用,這是不允許的
    2. 變數屬於類的執行個體對象
    3. 隨著類的執行個體被建立而分配記憶體空間

非靜態代碼塊
    直接由 { } 包起來的代碼,稱為非靜態代碼塊

靜態代碼塊
    直接由 static { } 包起來的代碼,稱為靜態代碼塊

類變數(靜態變數)、執行個體變數(非靜態變數)、靜態代碼塊、非靜態代碼塊的初始化時機
    由 static 關鍵字修飾的(如:類變數[靜態變數]、靜態代碼塊)將在類被初始化建立執行個體對象之前被初始化,而且是按順序從上到下依次被執行;
    沒有 static 關鍵字修飾的(如:執行個體變數[非靜態變數]、非靜態代碼塊)初始化實際上是會被提取到類的構造器中被執行的,但是會比類構造器中的 代碼塊優先執行到,其也是按順序從上到下依次被執行。


範例程式碼:

public class Statical { /**  * 靜態代碼塊 類變數(靜態變數)可以向前引用(即:先引用,再定義)  */ static {  name = "fancydeepin"; // name 的定義在使用之後  System.out.println("--->  靜態代碼塊被執行   <---"); } /**  * 類變數(靜態變數)在類的初始化之前初始化,無論類的執行個體將被建立多少個 凡 static修飾的,都將按位置被順序執行,所以, name  * 的值最終輸出 fancy 而不是上面的 fancydeepin  */ public static String name = "fancy"; // 類變數(靜態變數) private String mail = "myEmail"; // 執行個體變數(非靜態變數),定義時指定初始值,會比在構造器賦予值更早執行 public Statical() {  mail = "[email protected]";  System.out.println("---> 構造器代碼塊被執行 <---"); } /**  * 非靜態代碼塊 實際上,非靜態代碼塊在類初始化建立執行個體時,將會被提取到類的構造器中, 但是,非靜態代碼塊會比構造器中的代碼塊優先被執行  * 所以,mail 最終輸出的是類構造器中給定的值,也就是 [email protected] 而不是  * [email protected],更不是 myEmail  */ {  mail = "[email protected]";  System.out.println("---> 非靜態代碼塊被執行 <---"); } public static void main(String[] args) {  Statical statical = new Statical();  System.out.println(name);  System.out.println(statical.mail); }}


輸出結果:

--->  靜態代碼塊被執行   <---
---> 非靜態代碼塊被執行 <---
---> 構造器代碼塊被執行 <---
fancy
[email protected]


容易混淆的一個知識點

    靜態方法只允許直接訪問靜態成員,而執行個體方法中可以訪問靜態成員和執行個體成員,原因是類還沒有執行個體化,所執行個體成員也沒有被建立,靜態方法中因此也不能用this。


錯誤:class A{private int a;static void f(){a=1;}}正確:private static int a;static void f(){a=1;}}

當然靜態方法可以通過對象間接訪問非靜態成員的

public static void main(String[] args) {  Statical statical = new Statical();  System.out.println(name);  System.out.println(statical.mail);  }

    在靜態方法main中name是靜態變數可以直接存取,而mail屬於非靜態態變數,System.out.println(mail)直接存取會報錯,必須通過執行個體對象statical間接訪問。


本文出自 “一無所有-天行者” 部落格,請務必保留此出處http://tianxingzhe.blog.51cto.com/3390077/1656302

Java基礎-代碼執行順序(重要)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.