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