1.3 static 關(guān)鍵字

static 關(guān)鍵字

《Java編程思想》 中:static方法就是沒有this的方法

static 修飾的方法或者變量,不需要依賴實(shí)例對(duì)象就可以訪問,只要類被JVM加載了,就可以通過類名來(lái)訪問。

static 可以修飾方法,變量,還以編寫static代碼塊優(yōu)化程序性能

1. static 變量

static 修飾的變量稱為 靜態(tài)變量。

  • 靜態(tài)變量: 被所有對(duì)象共享,在內(nèi)存中只有一個(gè)副本,它當(dāng)且僅當(dāng)在類加載時(shí)候會(huì)被初始化。
  • 非靜態(tài)變量:為該對(duì)象所擁有,在內(nèi)存中存在多個(gè)副本,在對(duì)象創(chuàng)建的時(shí)候,初始化。

注意,前面這段總結(jié)是有點(diǎn)抽象,所以分別舉個(gè)例子加以詳細(xì)說明:

非靜態(tài)變量



public class TestMain {

    public static void main(String[] args) {

        new Apple();
    }
}


public class Apple {

    Orange orange = new Orange();

    public Apple() {
        System.out.println("Apple Construct");
    }


}

public class Orange {

    public Orange() {
        System.out.println("Orange Construct");
    }
}


運(yùn)行main方法后打印的后的輸出如下:

Orange Construct
Apple Construct

在執(zhí)行new Apple()這句代碼的時(shí)候,會(huì)創(chuàng)建Apple實(shí)例對(duì)象,然后執(zhí)行Apple()的無(wú)參構(gòu)造方法,在執(zhí)行構(gòu)造方法的時(shí)候,會(huì)先初始化父類構(gòu)造方法,這里Apple()對(duì)象沒有父類,解析來(lái)初始化Apple對(duì)象非靜態(tài)成員變量,也就是 Orange orange = new Orange(); 這段代碼,接下來(lái)Orange實(shí)例話的過程和Appple實(shí)例話的過程是一樣的。

實(shí)際上,如果我們對(duì)實(shí)例變量直接賦值或者使用實(shí)例代碼塊賦值,那么編譯器會(huì)將其中的代碼放到類的構(gòu)造函數(shù)中去,并且這些代碼會(huì)被放在對(duì)超類構(gòu)造函數(shù)的調(diào)用語(yǔ)句之后(還記得嗎?Java要求構(gòu)造函數(shù)的第一條語(yǔ)句必須是超類構(gòu)造函數(shù)的調(diào)用語(yǔ)句),構(gòu)造函數(shù)本身的代碼之前

靜態(tài)變量

在我們寫懶漢單例模式的時(shí)候,會(huì)用到靜態(tài)變量??聪旅娴睦?/p>

public class SingletonLazyNotSafe {

    private static SingletonLazyNotSafe instance = null;

    private SingletonLazyNotSafe() {

    }


    public static SingletonLazyNotSafe getInstance() {

        if (instance == null) {
            instance = new SingletonLazyNotSafe();
        }
        return instance;
    }
}

這種懶漢單例模式是非線程安全,但是它利于我們分析代碼。為什么說是懶漢呢,loazyLoad,就是因?yàn)?把靜態(tài)變量 instance 設(shè)為null,這是因?yàn)樵贘VM加載Class對(duì)象的時(shí)候,會(huì)在加載的最后一個(gè)階段初始化階段,初始化類的靜態(tài)域,如果像餓漢單例模式那也直接將 instance = SingletonLazyNotSafe(),那樣會(huì)直接在類加載階段就直接初始化了該對(duì)象,可能這個(gè)時(shí)候還沒有真正用到該對(duì)象,這樣造成內(nèi)存空間的浪費(fèi)。

JVM加載類的過程分為三個(gè)階段,第一個(gè)階段加載字節(jié)文件,第二個(gè)階段 鏈接字節(jié)文件, 驗(yàn)證字節(jié)文件安全,分配靜態(tài)域內(nèi)存,第三個(gè)階段,初始化,類加載最后階段,如果有父類,則先對(duì)其初始化,然后執(zhí)行靜態(tài)域的初始化。

?

2. static 方法

static 關(guān)鍵字修飾的方法,一般稱為靜態(tài)方法,靜態(tài)方法沒有關(guān)鍵字this。

類的構(gòu)造方法是不是靜態(tài)方法呢?答案是否定的,很明顯,構(gòu)造方法里面有this關(guān)鍵字,可以引用成員變量。

Java虛擬機(jī)規(guī)范第二版中定義了四種不同的字節(jié)碼指令來(lái)處理Java程序中不同種類的方法的調(diào)用:

  • invokestatic : 用于調(diào)用類(靜態(tài))方法
  • invokespecial :用于調(diào)用實(shí)例方法,特化于super方法調(diào)用、private方法調(diào)用與構(gòu)造器調(diào)用
  • invokevirtual :用于調(diào)用一般實(shí)例方法(包括聲明為final但不為private的實(shí)例方法)
  • invokeinterface :用于調(diào)用接口方法

invokestatic與invokespecial調(diào)用的目標(biāo)必然是可以靜態(tài)綁定的(比如不被繼承),因?yàn)樗鼈兌紵o(wú)法參與子類型多態(tài)。

invokevirtual與invokeinterface的則一般需要做運(yùn)行時(shí)綁定。

JVM實(shí)現(xiàn)可以有選擇的根據(jù)final或?qū)嶋H運(yùn)行時(shí)類層次或類型反饋等信息試圖進(jìn)行靜態(tài)綁定。

那么Java中的實(shí)例構(gòu)造器是不是“靜態(tài)方法”呢?從Java語(yǔ)言規(guī)范中給出的“靜態(tài)方法”的定義來(lái)看,答案是“否”——首先從Java語(yǔ)言規(guī)范對(duì)“方法”的定義來(lái)說,構(gòu)造器根本不是“方法”;其次,實(shí)例構(gòu)造器有一個(gè)隱式參數(shù),“this”,在實(shí)例構(gòu)造器中可以訪問“this”,可以通過“this”訪問到正在初始化的對(duì)象實(shí)例的所有實(shí)例成員。

?

3. static 代碼塊

static關(guān)鍵字還有一個(gè)比較關(guān)鍵的作用就是 用來(lái)形成靜態(tài)代碼塊以優(yōu)化程序性能。static塊可以置于類中的任何地方,類中可以有多個(gè)static塊。在類初次被加載的時(shí)候,會(huì)按照static塊的順序來(lái)執(zhí)行每個(gè)static塊,并且只會(huì)執(zhí)行一次。

為什么說static塊可以用來(lái)優(yōu)化程序性能,是因?yàn)樗奶匦?只會(huì)在類加載的時(shí)候執(zhí)行一次。

?

4. static 靜態(tài)內(nèi)部類

static還可以用來(lái)修飾內(nèi)部類,但是外部類不能用static修飾,編譯器會(huì)直接報(bào)錯(cuò)。

非static修飾的內(nèi)部類,不可以在其中定義static變量,或者static方法,或者static代碼塊。
非靜態(tài)內(nèi)部類,可以直接訪問外部類的成員變量和成員方法,哪怕是private修飾的

靜態(tài)內(nèi)部類,可以定義static變量,或者static方法,或者static代碼塊
靜態(tài)內(nèi)部類,不能外部類的成員變量和成員方法,靜態(tài)內(nèi)部類在實(shí)例化的時(shí)候不需要和外部類綁定。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容