關(guān)于java中的static關(guān)鍵字

最近在考慮一個問題,static關(guān)鍵字的作用。

在看了一篇博客后,自己感觸頗深,決定記錄在自己的日記當(dāng)中~
關(guān)于static關(guān)鍵字大家都所熟悉的就是他是一個修飾類屬性或者類方法的關(guān)鍵字。被static所修飾過的類屬性或者類方法不需要new出對象,直接通過類名點(diǎn)出來即可。例如:
創(chuàng)建一個Person類里面有一個被static修飾過的eye屬性。那么獲取屬性的時候直接通過
Person.eye就可以直接引用,而不需要new出一個實(shí)例。
在Person類中有一個eat的方法。那個該方法就是類方法。直接通過類名Person.eat();就能直接調(diào)用吃的方法。

被靜態(tài)修飾的屬性,統(tǒng)一數(shù)據(jù)該類的靜態(tài)資源,是類實(shí)例之中共享的,換言之,只要是通過該類new出來的實(shí)例獲取的資源都是統(tǒng)一的,大家共享的。一處變,處處變。

抽了一顆煙后,想了想,有三個問題:
在靜態(tài)方法中能不能使用非靜態(tài)的屬性呢?靜態(tài)方法中能不能使用靜態(tài)屬性呢?還有一個問題,在成員方法中能不能使用靜態(tài)。

靜態(tài)資源屬于類,是獨(dú)立與類而存在的,在JVM類加載機(jī)制的角度講,靜態(tài)資源是類在初始化的時候就加載了,而非靜態(tài)資源的話是在類new實(shí)例的時候加載的。重要的是,類的加載要早于new的時候的加載。所以對于上面的三個問題就有一個很明確的答案了。

1.在靜態(tài)方法中能不能是用非靜態(tài)的屬性呢?答案是:不能,因?yàn)樵趫?zhí)行靜態(tài)方法的時候,去獲取非靜態(tài)資源的時候那時候非靜態(tài)資源還沒有加載,靜態(tài)方法根本獲取不到。
2.在靜態(tài)方法中能不能獲取到靜態(tài)屬性呢?答案是:能,因?yàn)轭愒诔跏蓟臅r候靜態(tài)方法和靜態(tài)屬性都已經(jīng)在內(nèi)存當(dāng)中了,所以兩者都是認(rèn)識的當(dāng)然可以直接使用。
3.在成員方法中能不能獲取靜態(tài)資源呢?答案是:當(dāng)然能,靜態(tài)資源是優(yōu)先與成員方法而存在的,所以在new出實(shí)例之前靜態(tài)資源就已經(jīng)在內(nèi)存中了。所以當(dāng)然可以直接使用了!

靜態(tài)代碼塊

靜態(tài)代碼塊的話,只在類初始化的時候執(zhí)行,且只執(zhí)行一次。
看如下代碼:

public class A
{
    private static int a = B();
    
    static
    {
        System.out.println("Enter A.static block");
    }
    
    public static void main(String[] args)
    {
        new A();
    }
    
    public static int B()
    {
        System.out.println("Enter A.B()");
        return 1;
    }
}

看上面代碼的執(zhí)行順序:
當(dāng)執(zhí)行main方法的時候,調(diào)用了A類的無參構(gòu)造方法,然后依照順序?qū)?shù)進(jìn)行賦值,然后調(diào)用A類的B的靜態(tài)方法,然后執(zhí)行static靜態(tài)代碼塊。
所以輸出結(jié)果就為:
Enter A.B()
Enter a.static block

//父類
public class A
{
    static
    {
        System.out.println("A.static block");
    }
    
    public A()
    {
        System.out.println("A.constructor()");
    }
}
//子類
public class B extends A
{
    static 
    {
        System.out.println("B.static block");
    }
    
    public B()
    {
        System.out.println("B.constructor()");
    }
    
    public static void main(String[] args)
    {
        new B();
        new B();
    }
}

該代碼的執(zhí)行順序是:
在main方法中執(zhí)行B的無參構(gòu)造方法,當(dāng)去去加載B類,B類初始化的時候會去先去加載B類的父類A類,A類的靜態(tài)代碼塊首先執(zhí)行,執(zhí)行完之后才到B類的靜態(tài)代碼塊,然后才到A類的無參構(gòu)造方法,相繼之后執(zhí)行B類的構(gòu)造方法。這是B類的第一個無參構(gòu)造方法執(zhí)行完畢之后的結(jié)果,當(dāng)?shù)诙€無參構(gòu)造方法執(zhí)行的時候,發(fā)現(xiàn)父類和子類的靜態(tài)代碼塊都執(zhí)行過之后,便不會再執(zhí)行,只會去執(zhí)行父類的無參構(gòu)造方法和子類的無參構(gòu)造方法。所以執(zhí)行結(jié)果為:
A.static block
B.static block
A.constructor()
B.constructor()
A.constructor()
B.constructor()

由上面的代碼運(yùn)行結(jié)果可以看出:

靜態(tài)資源的加載順序嚴(yán)格按照靜態(tài)資源的定義順序來執(zhí)行。并且靜態(tài)代碼塊有且只被加載一次。

static修飾類

static關(guān)鍵字一般不修飾類:
如果真要修飾類的話,那么就必然是靜態(tài)內(nèi)部類。靜態(tài)內(nèi)部類不能直接使用外部類的非靜態(tài)資源,但是可以通過實(shí)例化外部成員所使用,至于外部類的靜態(tài)資源的話就可以直接通過外部類的類名點(diǎn)出來使用,如果是使用內(nèi)部類的屬性的話,就直接使用就好。在實(shí)例化靜態(tài)內(nèi)部類的時候,和實(shí)例化非靜態(tài)的內(nèi)部類不同,不需要先new出外部類然后再new出內(nèi)部類,當(dāng)實(shí)例靜態(tài)內(nèi)部類的時候直接new出內(nèi)部類就好了。

本篇文章只為自己一個小白的學(xué)習(xí)日記,當(dāng)中摘自了很多--IT·達(dá)人的博客。在此很感謝達(dá)人博主如果有很多不妥的地方請直接聯(lián)系本人。然后在此再次感謝!謝謝

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

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,812評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,680評論 19 139
  • Advanced Language Features 知識點(diǎn):一. static修飾符 static修飾符可以用來...
    風(fēng)景涼閱讀 507評論 0 0
  • 一、什么是單例模式:1、就我本身理解而言,我認(rèn)為的單例:單例在整個工程中,就相當(dāng)于一個全局變量,就是不論在哪里需要...
    weyan閱讀 321評論 0 1
  • 打卡的重要性: 一形成儀式感, 二打卡是提醒自己,不是做給別人看, 三分享到朋友圈是為了用一個生命去影響更多生命,...
    7312a7a77e89閱讀 3,321評論 0 2

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