成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java代碼執(zhí)行順序

hosition / 2674人閱讀

摘要:沒有關鍵字修飾的如實例變量非靜態(tài)變量非靜態(tài)代碼塊初始化實際上是會被提取到類的構造器中被執(zhí)行的,但是會比類構造器中的代碼塊優(yōu)先執(zhí)行到,非靜態(tài)實例變量非靜態(tài)代碼塊的地位是相等的,它們將按順序被執(zhí)行。

閱讀原文:Java代碼執(zhí)行順序

程序中代碼執(zhí)行的順序非常重要,稍有不慎便會是程序運行出錯,那么我將結合實例來分析代碼中的執(zhí)行。

名詞解釋

首先了解幾個名詞:

非靜態(tài)代碼塊
直接由 { } 包起來的代碼,稱為非靜態(tài)代碼塊
靜態(tài)代碼塊
直接由 static { } 包起來的代碼,稱為靜態(tài)代碼塊
形參

比如你定義一個函數(shù)void add(int a, int b),這里的a和b就是形參。
當你進行函數(shù)調(diào)用的時候,add(1, 2),這里的1和2就是實參。

向前引用

所謂向前引用,就是在定義類、接口、方法、變量之前使用它們。

成員變量
在類體里面定義的變量稱為成員變量;
如果該成員變量有 static 關鍵字修飾,則該成員變量稱為 靜態(tài)變量 或 類變量;
如果該成員變量沒有 static 關鍵字修飾,則該成員變量被稱為 非靜態(tài)變量 或 實例變量。
局部變量
形參、方法內(nèi)定義的變量、代碼塊中定義的變量,都屬于局部變量。
類變量 (靜態(tài)變量)
可以向前引用
變量屬于類本身
類變量不依賴類的實例,類變量只在初始化時候在方法區(qū)中被分配一次空間,無論類的實例被創(chuàng)建幾次,都不再為類變量分配空間
通過類的任意一個實例來訪問類變量,底層都將將其轉(zhuǎn)為通過類本身來訪問類變量,它們的效果是一樣的
一旦類變量的值被改變,通過類或類的任意一個實例來訪問類變量,得到的都將是被改變后的值
將在類的初始化之前初始化
實例變量(非靜態(tài)變量)
不能向前引用,如果向前引用,則稱為非法向前引用,這是不允許的
變量屬于類的實例對象
隨著類的實例被創(chuàng)建而分配內(nèi)存空間

實例演示
public class Parent {
    public int parentNum=0;
    public static int staticParentNum=0;
    
    {
        System.out.println("Parent---執(zhí)行非靜態(tài)代碼塊了1!");
    }
    
    {
        System.out.println("Parent---執(zhí)行非靜態(tài)代碼塊了2!");
    }
    
    static{
        System.out.println("Parent---執(zhí)行靜態(tài)代碼塊了1!");
    }
    
    static{
        System.out.println("Parent---執(zhí)行靜態(tài)代碼塊了2!");
    }

    public Parent(){
        System.out.println("Parent---無參構造函數(shù)!");
    }
    public Parent(int parentNum){
        this.parentNum=parentNum;
        System.out.println("Parent---有參構造函數(shù)!");
        
    }

    public void ParentMethod(int parentNum){
        this.parentNum=parentNum;
        System.out.println("Parent---非靜態(tài)方法/parentNum="+parentNum);
    }
    
    public static void staticParentMethod(int staticParentNum){
        Parent.staticParentNum=staticParentNum;
        System.out.println("Parent---靜態(tài)方法/staticParentNum="+staticParentNum);
    }
    
}
public class Child extends Parent{

    public int childNum=0;
    public static int staticChildNum=0;
    
    {
        System.out.println("Child---執(zhí)行非靜態(tài)代碼塊了1!");
    }
    
    {
        System.out.println("Child---執(zhí)行非靜態(tài)代碼塊了2!");
    }
    
    static{
        System.out.println("Child---執(zhí)行靜態(tài)代碼塊了1!");
    }
    
    static{
        System.out.println("Child---執(zhí)行靜態(tài)代碼塊了2!");
    }

    public Child(){
        super();
        System.out.println("Child---無參構造函數(shù)!");
    }
    
    public Child(int childNum){
        super(childNum);
        System.out.println("Child---有參構造函數(shù)!");
    }
    
    public void childMethod(int childNum){
        this.childNum=childNum;
        System.out.println("Child--非靜態(tài)方法/childNum="+childNum);
    }
    
    public static void staticChildMethod(int staticChildNum){
        Child.staticChildNum=staticChildNum;
        System.out.println("Child---靜態(tài)方法/staticChildNum="+staticChildNum);
    }

    
}
package test;

public class Test {

//    static{
//        System.out.println("Test---靜態(tài)代碼塊!");
//    }
    public static void main(String[] args) {
        int key=10;
        switch (key) {
        case 0:
            Parent parent=new Parent();
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            Parent---執(zhí)行非靜態(tài)代碼塊了1!
//            Parent---執(zhí)行非靜態(tài)代碼塊了2!
//            Parent---無參構造函數(shù)!
//          說明:先加載靜態(tài)代碼塊,后加載非靜態(tài)代碼塊
        case 1:
            Child b= new Child();
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            Child---執(zhí)行靜態(tài)代碼塊了1!
//            Child---執(zhí)行靜態(tài)代碼塊了2!
//            Parent---執(zhí)行非靜態(tài)代碼塊了1!
//            Parent---執(zhí)行非靜態(tài)代碼塊了2!
//            Parent---無參構造函數(shù)!
//            Child---執(zhí)行非靜態(tài)代碼塊了1!
//            Child---執(zhí)行非靜態(tài)代碼塊了2!
//            Child---無參構造函數(shù)!
//            說明:創(chuàng)建子類,會先執(zhí)行父類,先執(zhí)行父類靜態(tài)——>子類靜態(tài)——>父類非靜態(tài)——>父類構造
//——>子類非靜態(tài)——>子類構造
        case 2:
            Child c= new Child(4);
            //這個構造函數(shù)中指明了調(diào)用父類的有參構造函數(shù),若不指定,則調(diào)用父類無參構造函數(shù)
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            Child---執(zhí)行靜態(tài)代碼塊了1!
//            Child---執(zhí)行靜態(tài)代碼塊了2!
//            Parent---執(zhí)行非靜態(tài)代碼塊了1!
//            Parent---執(zhí)行非靜態(tài)代碼塊了2!
//            Parent---有參構造函數(shù)!
//            Child---執(zhí)行非靜態(tài)代碼塊了1!
//            Child---執(zhí)行非靜態(tài)代碼塊了2!
//            Child---有參構造函數(shù)!
            說明:靜態(tài)代碼塊或非靜態(tài)代碼塊執(zhí)行順序,按照代碼前后編寫順序。
        case 3:
            Child d= new Child();
            Child e= new Child(4);
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            Child---執(zhí)行靜態(tài)代碼塊了1!
//            Child---執(zhí)行靜態(tài)代碼塊了2!
//            Parent---執(zhí)行非靜態(tài)代碼塊了1!
//            Parent---執(zhí)行非靜態(tài)代碼塊了2!
//            Parent---無參構造函數(shù)!
//            Child---執(zhí)行非靜態(tài)代碼塊了1!
//            Child---執(zhí)行非靜態(tài)代碼塊了2!
//            Child---無參構造函數(shù)!
//            Parent---執(zhí)行非靜態(tài)代碼塊了1!
//            Parent---執(zhí)行非靜態(tài)代碼塊了2!
//            Parent---有參構造函數(shù)!
//            Child---執(zhí)行非靜態(tài)代碼塊了1!
//            Child---執(zhí)行非靜態(tài)代碼塊了2!
//            Child---有參構造函數(shù)!
            說明:創(chuàng)建多個子類,但父類靜態(tài)代碼塊只執(zhí)行一次。
        case 4:
            Child.staticChildMethod(4);
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            Child---執(zhí)行靜態(tài)代碼塊了1!
//            Child---執(zhí)行靜態(tài)代碼塊了2!
//            Child---靜態(tài)方法/staticChildNum=4
            說明:靜態(tài)方法只可以調(diào)用靜態(tài)變量。
        case 5:
            Parent.staticParentMethod(5);
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            Parent---靜態(tài)方法/staticParentNum=5
            說明:靜態(tài)方法可通過 父類名.靜態(tài)方法() 調(diào)用。
        case 6:
            System.out.println("父類的靜態(tài)變量值staticParentNum="+Parent.staticParentNum);
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            父類的靜態(tài)變量值staticParentNum=0
            說明:調(diào)用靜態(tài)變量時,靜態(tài)代碼塊會執(zhí)行。
        case 7:
            System.out.println("子類的靜態(tài)變量值staticChildNum="+Child.staticChildNum);
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            Child---執(zhí)行靜態(tài)代碼塊了1!
//            Child---執(zhí)行靜態(tài)代碼塊了2!
//            子類的靜態(tài)變量值staticChildNum=0
            說明:調(diào)用子類靜態(tài)變量,父類靜態(tài)代碼塊和子類靜態(tài)代碼塊會被執(zhí)行。
        case 8:
            System.out.println("父類的靜態(tài)變量值staticParentNum="+Parent.staticParentNum);
            System.out.println("子類的靜態(tài)變量值staticChildNum="+Child.staticChildNum);
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            父類的靜態(tài)變量值staticParentNum=0
//            Child---執(zhí)行靜態(tài)代碼塊了1!
//            Child---執(zhí)行靜態(tài)代碼塊了2!
//            子類的靜態(tài)變量值staticChildNum=0
            
        case 9:
            Child f= new Child();
            f.ParentMethod(3);
            break;
//            Parent---執(zhí)行靜態(tài)代碼塊了1!
//            Parent---執(zhí)行靜態(tài)代碼塊了2!
//            Child---執(zhí)行靜態(tài)代碼塊了1!
//            Child---執(zhí)行靜態(tài)代碼塊了2!
//            Parent---執(zhí)行非靜態(tài)代碼塊了1!
//            Parent---執(zhí)行非靜態(tài)代碼塊了2!
//            Parent---無參構造函數(shù)!
//            Child---執(zhí)行非靜態(tài)代碼塊了1!
//            Child---執(zhí)行非靜態(tài)代碼塊了2!
//            Child---無參構造函數(shù)!
//            Parent---非靜態(tài)方法/parentNum=3
            說明:創(chuàng)建子類,用子類調(diào)用父類方法,非靜態(tài)方法可以調(diào)用靜態(tài)變量。

        default:
            break;
        }

    }

}
總結

Java代碼初始化順序

由 static 關鍵字修飾的(如:類變量(靜態(tài)變量)、靜態(tài)代碼塊)將在類被初始化創(chuàng)建實例對象之前被初始化,而且是按順序從上到下依次被執(zhí)行。靜態(tài)(類變量、靜態(tài)代碼塊)屬于類本身,不依賴于類的實例。

沒有 static 關鍵字修飾的(如:實例變量(非靜態(tài)變量)、非靜態(tài)代碼塊)初始化實際上是會被提取到類的構造器中被執(zhí)行的,但是會比類構造器中的代碼塊優(yōu)先執(zhí)行到,非靜態(tài)(實例變量、非靜態(tài)代碼塊)的地位是相等的,它們將按順序被執(zhí)行。

類變量(靜態(tài)變量)、實例變量(非靜態(tài)變量)、靜態(tài)代碼塊、非靜態(tài)代碼塊的初始化時機

由 static 關鍵字修飾的(如:類變量[靜態(tài)變量]、靜態(tài)代碼塊)將在類被初始化創(chuàng)建實例對象之前被初始化,而且是按順序從上到下依次被執(zhí)行;

沒有 static 關鍵字修飾的(如:實例變量[非靜態(tài)變量]、非靜態(tài)代碼塊)初始化實際上是會被提取到類的構造器中被執(zhí)行的,但是會比類構造器中的 代碼塊優(yōu)先執(zhí)行到,其也是按順序從上到下依次被執(zhí)行。

容易混淆的一個知識點
靜態(tài)方法只允許直接訪問靜態(tài)成員,而實例方法中可以訪問靜態(tài)成員和實例成員,原因是類還沒有實例化,所實例成員也沒有被創(chuàng)建,靜態(tài)方法中因此也不能用this。

歡迎關注公眾號交流!

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/73700.html

相關文章

  • Java 并發(fā)編程(學習)

    摘要:并發(fā)編程的挑戰(zhàn)并發(fā)編程的目的是為了讓程序運行的更快,但是,并不是啟動更多的線程就能讓程序最大限度的并發(fā)執(zhí)行。的實現(xiàn)原理與應用在多線程并發(fā)編程中一直是元老級角色,很多人都會稱呼它為重量級鎖。 并發(fā)編程的挑戰(zhàn) 并發(fā)編程的目的是為了讓程序運行的更快,但是,并不是啟動更多的線程就能讓程序最大限度的并發(fā)執(zhí)行。如果希望通過多線程執(zhí)行任務讓程序運行的更快,會面臨非常多的挑戰(zhàn):(1)上下文切換(2)死...

    NervosNetwork 評論0 收藏0
  • 深入理解Java內(nèi)存模型(三)——順序一致性

    摘要:下面是該程序在兩個內(nèi)存模型中的執(zhí)行時序?qū)Ρ葓D在順序一致性模型中,所有操作完全按程序的順序串行執(zhí)行。不保證未同步程序的執(zhí)行結果與該程序在順序一致性模型中的執(zhí)行結果一致。 前情提要 深入理解Java內(nèi)存模型(二)——重排序 數(shù)據(jù)競爭與順序一致性保證 當程序未正確同步時,就會存在數(shù)據(jù)競爭。java內(nèi)存模型規(guī)范對數(shù)據(jù)競爭的定義如下: 在一個線程中寫一個變量, 在另一個線程讀同一個變量,...

    aristark 評論0 收藏0
  • 《深入理解 Java 內(nèi)存模型》讀書筆記

    摘要:前提深入理解內(nèi)存模型程曉明著,該書在以前看過一遍,現(xiàn)在學的東西越多,感覺那塊越重要,于是又再細看一遍,于是便有了下面的讀書筆記總結。同步同步是指程序用于控制不同線程之間操作發(fā)生相對順序的機制。線程之間的通信由內(nèi)存模型控制。 showImg(https://segmentfault.com/img/remote/1460000013474312?w=1920&h=1271); 前提 《深...

    xuexiangjys 評論0 收藏0
  • 《深入理解 Java 內(nèi)存模型》讀書筆記

    摘要:前提深入理解內(nèi)存模型程曉明著,該書在以前看過一遍,現(xiàn)在學的東西越多,感覺那塊越重要,于是又再細看一遍,于是便有了下面的讀書筆記總結。同步同步是指程序用于控制不同線程之間操作發(fā)生相對順序的機制。線程之間的通信由內(nèi)存模型控制。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6RtPu3BNx3zps1JhSmPICRw7QgeOmxOfTb...

    姘存按 評論0 收藏0
  • Java并發(fā)編程:從根源上解析volatile關鍵字的實現(xiàn)

    摘要:并發(fā)編程關鍵字解析解析概覽內(nèi)存模型的相關概念并發(fā)編程中的三個概念內(nèi)存模型深入剖析關鍵字使用關鍵字的場景內(nèi)存模型的相關概念緩存一致性問題。事實上,這個規(guī)則是用來保證程序在單線程中執(zhí)行結果的正確性,但無法保證程序在多線程中執(zhí)行的正確性。 Java并發(fā)編程:volatile關鍵字解析 1、解析概覽 內(nèi)存模型的相關概念 并發(fā)編程中的三個概念 Java內(nèi)存模型 深入剖析volatile關鍵字 ...

    CNZPH 評論0 收藏0
  • 深入理解Java內(nèi)存模型(二)——重排序

    摘要:前情提要深入理解內(nèi)存模型一基礎編譯器運行時會對指令進行重排序。以處理器的猜測執(zhí)行為例,執(zhí)行線程的處理器可以提前讀取并計算,然后把計算結果臨時保存到一個名為重排序緩沖的硬件緩存中。請看下篇深入理解內(nèi)存模型三順序一致性 前情提要 深入理解Java內(nèi)存模型(一)——基礎 Java編譯器、運行時會對指令進行重排序。這種重排序在單線程和多線程情況下分別有什么影響呢? 數(shù)據(jù)依賴性 如果兩個操...

    tunny 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<