使用static修飾符可以使成員變量或方法具有類級(jí)別而非實(shí)例級(jí)別的特性兽泄,即被靜態(tài)修飾的成員在所有該類的實(shí)例之間是共享的蠢琳。因此拭抬,應(yīng)該根據(jù)具體情況考慮何時(shí)適合使用static修飾符吟逝。
以下是幾個(gè)適合使用static修飾符的場(chǎng)景:
常量定義
經(jīng)常使用的常量可以使用靜態(tài)修飾符聲明為靜態(tài)常量占业,這樣就可以在整個(gè)應(yīng)用程序中訪問(wèn)它們绒怨。
例如:public static final int MAX_VALUE = 1000;
工廠方法
在某些情況下,工廠方法可以使用靜態(tài)修飾符創(chuàng)建一個(gè)對(duì)象實(shí)例谦疾。
例如:public static Logger getLogger();
共享的資源
將函數(shù)或成員變量設(shè)置為靜態(tài)的南蹂,可以使它們?cè)谒蓄惖膶?shí)例之間共享。靜態(tài)變量和方法被所有實(shí)例共享念恍,因此可以用來(lái)實(shí)現(xiàn)共享的資源庫(kù)六剥。
例如:private static Connection conn;
嵌套類
在Java中晚顷,嵌套類可以是靜態(tài)的,靜態(tài)嵌套類只能訪問(wèn)外部類的靜態(tài)成員疗疟,因此如果嵌套類沒(méi)有必要訪問(wèn)外部類的非靜態(tài)成員该默,那么可以使用靜態(tài)嵌套類。
例如:public static class MyStaticNestedClass { }
需要注意的是策彤,使用靜態(tài)修飾符需要謹(jǐn)慎栓袖,因?yàn)樗鼈兙哂腥中浴lo態(tài)方法和變量可以在不同的地方被訪問(wèn)和修改店诗,因此可能會(huì)引起非預(yù)期的副作用裹刮。因此,應(yīng)該根據(jù)具體情況謹(jǐn)慎使用靜態(tài)修飾符庞瘸。
以下是一些不適合使用static修飾符的場(chǎng)景:
實(shí)例變量
實(shí)例變量與類的每個(gè)實(shí)例相關(guān)聯(lián)捧弃,它們的值在每個(gè)實(shí)例之間不共享。因此擦囊,在多個(gè)實(shí)例之間共享變量時(shí)违霞,不能使用靜態(tài)變量。實(shí)例方法
實(shí)例方法是與類的每個(gè)實(shí)例相關(guān)聯(lián)的方法霜第,它們只能通過(guò)創(chuàng)建對(duì)象實(shí)例來(lái)訪問(wèn)葛家。因?yàn)殪o態(tài)方法在每個(gè)實(shí)例之間共享,所以不能用它們來(lái)訪問(wèn)實(shí)例數(shù)據(jù)或?qū)嵗椒ā?/p>單例模式
在單例模式中泌类,只應(yīng)該有一個(gè)實(shí)例癞谒,因此不能使用靜態(tài)變量和方法,因?yàn)樗鼈儠?huì)在整個(gè)應(yīng)用程序中共享刃榨。線程不安全的類
如果一個(gè)類是線程不安全的弹砚,那么使用靜態(tài)變量和方法來(lái)訪問(wèn)它們可能是危險(xiǎn)的,因?yàn)樵擃惪赡軙?huì)在多個(gè)線程之間共享枢希,并可能導(dǎo)致意外的后果桌吃。
總之,如果想要在多個(gè)實(shí)例之間共享數(shù)據(jù)或方法苞轿,那么靜態(tài)修飾符是一個(gè)合理的選擇茅诱。但是,需要明確靜態(tài)變量和方法適合的范圍搬卒,而不是隨意的使用它們瑟俭,這樣才能確保代碼的正確性和可維護(hù)性。
另外契邀,需要注意的是摆寄,使用靜態(tài)修飾符還存在一些需要特別注意的問(wèn)題:
靜態(tài)代碼塊的執(zhí)行順序
Java中,靜態(tài)初始化器和變量初始化器代碼塊是隨著類的初始化而執(zhí)行的。當(dāng)類第一次被加載時(shí)微饥,它所有的靜態(tài)代碼塊會(huì)被執(zhí)行逗扒,因此必須注意執(zhí)行順序,避免引用尚未初始化的變量欠橘。靜態(tài)變量的生命周期
靜態(tài)變量的生命周期是在整個(gè)應(yīng)用程序中矩肩,它們不會(huì)像實(shí)例變量那樣在實(shí)例銷毀時(shí)被釋放。因此简软,如果將靜態(tài)變量賦予了不正確的值蛮拔,那么這個(gè)值將會(huì)一直存在述暂,直到程序終止痹升。并發(fā)訪問(wèn)問(wèn)題
由于靜態(tài)變量和方法可以在不同的地方被訪問(wèn)和修改,因此在多線程環(huán)境下可能會(huì)出現(xiàn)并發(fā)訪問(wèn)問(wèn)題畦韭,導(dǎo)致線程安全問(wèn)題疼蛾。需要使用線程同步控制來(lái)避免這種情況。
總的來(lái)說(shuō)艺配,在使用靜態(tài)修飾符時(shí)察郁,需要考慮到它們的適用范圍,并謹(jǐn)慎使用转唉,才能避免意外的副作用和錯(cuò)誤皮钠,并確保代碼的正確性和可維護(hù)性。
講一個(gè)赠法,我剛犯的錯(cuò):
public class OrgPushRuleMatchResultBO {
/**
* 規(guī)則配置匹配成功后,構(gòu)建的組織推單記錄列表
*/
private static List<OrganizationPushOrderRecordEntity> orgPushOrderRecords = new CopyOnWriteArrayList<>();
public void addOrgPushOrder(final OrganizationPushOrderRecordEntity organizationPushOrderRecord) {
orgPushOrderRecords.add(organizationPushOrderRecord);
}
}
定義對(duì)象的時(shí)候麦轰,我對(duì)可能不安全的類加上了static,當(dāng)時(shí)考慮到ArrayList是線程不安全的砖织,所以特意使用了CopyOnWriteArrayList款侵。
但沒(méi)成想,這里的list是被實(shí)例之間共享的侧纯,這樣多個(gè)實(shí)例都可以訪問(wèn)到這個(gè)list新锈,那么就不是我想要的結(jié)果了,我想要的是彼此不可見(jiàn)眶熬。
好基礎(chǔ)的bug啊妹笆,算是補(bǔ)上了。