Java中的static靜態(tài)代碼塊的使用詳解
一.與靜態(tài)方法的比較
一般情況下,如果有些代碼必須在項目啟動的時候就執(zhí)行的時候,需要使用靜態(tài)代碼塊,這種代碼是主動執(zhí)行的;需要在項目啟動的時候就初始化,在不創(chuàng)建對象的情況下,其他程序來調(diào)用的時候,需要使用靜態(tài)方法,靜態(tài)方法在類加載的時候 就已經(jīng)加載 可以用類名直接調(diào)用 比如main方法就必須是靜態(tài)的 這是程序入口。兩者的區(qū)別就是:靜態(tài)代碼塊是自動執(zhí)行的; 靜態(tài)方法是被調(diào)用的時候才執(zhí)行的。
二.靜態(tài)方法注意事項
使用類的靜態(tài)方法時,注意:
a.在靜態(tài)方法里只能直接調(diào)用同類中其他的靜態(tài)成員(包括變量和方法),而不能直接訪問類中的非靜態(tài)成員。這是因為,對于非靜態(tài)的方法和變量,需要先創(chuàng)建類的實例對象后才可使用,而靜態(tài)方法在使用前
不用創(chuàng)建任何對象。
b.靜態(tài)方法不能以任何方式引用this和super關(guān)鍵字,因為靜態(tài)方法在使用前不用創(chuàng)建任何實例對象,當(dāng)靜態(tài)方法調(diào)用時,this所引用的對象根本沒有產(chǎn)生(this關(guān)鍵字只能在方法內(nèi)部使用,表示對“調(diào)用方法的那
個對象”的引用)。
靜態(tài)變量是屬于整個類的變量而不是屬于某個對象的。注意不能把任何方法體內(nèi)的變量聲明為靜態(tài),例如: fun() { static int i=0;//非法。 }
三.程序舉例
public class TestStaticCon {
public static int a = 0;
static {
a = 10;
System.out.println("父類的靜態(tài)代碼塊在執(zhí)行a=" + a);
}
{
a = 8;
System.out.println("父類的非靜態(tài)代碼塊在執(zhí)行a=" + a);
}
public TestStaticCon() {
this("a在父類帶參構(gòu)造方法中的值:" + TestStaticCon.a); // 調(diào)用另外一個構(gòu)造方法
System.out.println(a);
System.out.println("父類無參構(gòu)造方法在執(zhí)行a=" + a);
}
public TestStaticCon(String n) {
System.out.println(n);
System.out.println(a);
}
public static void main(String[] args) {
TestStaticCon tsc = null;
System.out.println("!!!!!!!!!!!!!!!!!!!!!");
tsc = new TestStaticCon();
}
}
運行結(jié)果:
父類的靜態(tài)代碼塊在執(zhí)行a=10
!!!!!!!!!!!!!!!!!!!!!
父類的非靜態(tài)代碼塊在執(zhí)行a=8
a在父類帶參構(gòu)造方法中的值:10
8
8
父類無參構(gòu)造方法在執(zhí)行a=8
四.網(wǎng)友提供
public class StaticBlock {
static {
System.out.println("靜態(tài)塊");
}
{
System.out.println("構(gòu)造塊,在類中定義");
}
public StaticBlock() {
System.out.println("構(gòu)造方法執(zhí)行");
}
public static void main(String[] args) {
new StaticBlock();
new StaticBlock();
}
}
靜態(tài)塊
構(gòu)造塊,在類中定義
構(gòu)造方法執(zhí)行
構(gòu)造塊,在類中定義
構(gòu)造方法執(zhí)行
結(jié)論:靜態(tài)代碼塊是在類加載時自動執(zhí)行的,非靜態(tài)代碼塊是在創(chuàng)建對象時自動執(zhí)行的代碼,不創(chuàng)建對象不執(zhí)行該類的非靜態(tài)代碼塊。且執(zhí)行順序為靜態(tài)代碼塊------非靜態(tài)代碼塊----構(gòu)造函數(shù)。
其中讓我疑惑的是“a在父類帶參構(gòu)造方法中的值:10”,我再想那時候為什么不是8,debug了(F11,不能直接設(shè)置斷點然后運行,那樣和直接運行沒區(qū)別),發(fā)現(xiàn)先進(jìn)入了無參的構(gòu)造方法,執(zhí)行了第一條語句并且切換到了另一個構(gòu)造方法(不管是不是反正第一句都要執(zhí)行,此時a還是10,非靜態(tài)代碼塊還未執(zhí)行),提示找不到源,不管是不是這條語句都提示了這個警告(不算錯誤,因為程序繼續(xù)正常運行),然后運行了非靜態(tài)代碼塊,繼而從有參的構(gòu)造方法處繼續(xù)執(zhí)行……
相關(guān)文章
Java后臺防止客戶端重復(fù)請求、提交表單實現(xiàn)原理
這篇文章主要介紹了Java后臺防止客戶端重復(fù)請求、提交表單實現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12【IntelliJ IDEA】Maven構(gòu)建自己的第一個Java后臺的方法
本篇文章主要介紹了Maven構(gòu)建自己的第一個Java后臺的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12使用Spring MVC攔截器實現(xiàn)日志記錄的方法
本篇文章主要介紹了使用Spring MVC攔截器實現(xiàn)日志記錄的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04Java實戰(zhàn)之電影在線觀看系統(tǒng)的實現(xiàn)
這篇文章主要介紹了如何利用Java實現(xiàn)電影在線觀看系統(tǒng),文中用到的技術(shù)有:JSP、Spring、SpringMVC、MyBatis等,感興趣的可以了解一下2022-04-04一文帶你深入理解Java?AbstractQueuedSynchronizer
在并發(fā)編程中,鎖是一種保證線程安全的方式,這篇文章主要為大家介紹了AbstractQueuedSynchronizer(AQS)的數(shù)據(jù)結(jié)構(gòu)及實現(xiàn)原理,感興趣的小伙伴可以了解一下2023-07-07Java線程同步機制_動力節(jié)點Java學(xué)院整理
在之前,已經(jīng)學(xué)習(xí)到了線程的創(chuàng)建和狀態(tài)控制,但是每個線程之間幾乎都沒有什么太大的聯(lián)系??墒怯械臅r候,可能存在多個線程多同一個數(shù)據(jù)進(jìn)行操作,這樣,可能就會引用各種奇怪的問題?,F(xiàn)在就來學(xué)習(xí)多線程對數(shù)據(jù)訪問的控制吧2017-05-05