最近在考慮一個問題,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)系本人。然后在此再次感謝!謝謝