java對象中什么時候適合用static修飾符踩坑解決記錄
static修飾符
使用static修飾符可以使成員變量或方法具有類級別而非實例級別的特性,即被靜態(tài)修飾的成員在所有該類的實例之間是共享的。因此,應(yīng)該根據(jù)具體情況考慮何時適合使用static修飾符。
適用static修飾符場景
- 常量定義
經(jīng)常使用的常量可以使用靜態(tài)修飾符聲明為靜態(tài)常量,這樣就可以在整個應(yīng)用程序中訪問它們。
例如:public static final int MAX_VALUE = 1000;
- 工廠方法
在某些情況下,工廠方法可以使用靜態(tài)修飾符創(chuàng)建一個對象實例。
例如:public static Logger getLogger();
- 共享的資源
將函數(shù)或成員變量設(shè)置為靜態(tài)的,可以使它們在所有類的實例之間共享。靜態(tài)變量和方法被所有實例共享,因此可以用來實現(xiàn)共享的資源庫。
例如:private static Connection conn;
- 嵌套類
在Java中,嵌套類可以是靜態(tài)的,靜態(tài)嵌套類只能訪問外部類的靜態(tài)成員,因此如果嵌套類沒有必要訪問外部類的非靜態(tài)成員,那么可以使用靜態(tài)嵌套類。
例如:public static class MyStaticNestedClass { }
需要注意的是,使用靜態(tài)修飾符需要謹(jǐn)慎,因為它們具有全局性。靜態(tài)方法和變量可以在不同的地方被訪問和修改,因此可能會引起非預(yù)期的副作用。因此,應(yīng)該根據(jù)具體情況謹(jǐn)慎使用靜態(tài)修飾符。
不適用static修飾符場景
- 實例變量
實例變量與類的每個實例相關(guān)聯(lián),它們的值在每個實例之間不共享。因此,在多個實例之間共享變量時,不能使用靜態(tài)變量。
- 實例方法
實例方法是與類的每個實例相關(guān)聯(lián)的方法,它們只能通過創(chuàng)建對象實例來訪問。因為靜態(tài)方法在每個實例之間共享,所以不能用它們來訪問實例數(shù)據(jù)或?qū)嵗椒ā?/p>
- 單例模式
在單例模式中,只應(yīng)該有一個實例,因此不能使用靜態(tài)變量和方法,因為它們會在整個應(yīng)用程序中共享。
- 線程不安全的類
如果一個類是線程不安全的,那么使用靜態(tài)變量和方法來訪問它們可能是危險的,因為該類可能會在多個線程之間共享,并可能導(dǎo)致意外的后果。
總之,如果想要在多個實例之間共享數(shù)據(jù)或方法,那么靜態(tài)修飾符是一個合理的選擇。但是,需要明確靜態(tài)變量和方法適合的范圍,而不是隨意的使用它們,這樣才能確保代碼的正確性和可維護(hù)性。
另外,需要注意的是,使用靜態(tài)修飾符還存在一些需要特別注意的問題:
- 靜態(tài)代碼塊的執(zhí)行順序
Java中,靜態(tài)初始化器和變量初始化器代碼塊是隨著類的初始化而執(zhí)行的。當(dāng)類第一次被加載時,它所有的靜態(tài)代碼塊會被執(zhí)行,因此必須注意執(zhí)行順序,避免引用尚未初始化的變量。
- 靜態(tài)變量的生命周期
靜態(tài)變量的生命周期是在整個應(yīng)用程序中,它們不會像實例變量那樣在實例銷毀時被釋放。因此,如果將靜態(tài)變量賦予了不正確的值,那么這個值將會一直存在,直到程序終止。
- 并發(fā)訪問問題
由于靜態(tài)變量和方法可以在不同的地方被訪問和修改,因此在多線程環(huán)境下可能會出現(xiàn)并發(fā)訪問問題,導(dǎo)致線程安全問題。需要使用線程同步控制來避免這種情況。
總的來說,在使用靜態(tài)修飾符時,需要考慮到它們的適用范圍,并謹(jǐn)慎使用,才能避免意外的副作用和錯誤,并確保代碼的正確性和可維護(hù)性。
踩坑
講一個,我剛犯的錯:
public class OrgPushRuleMatchResultBO { /** * 規(guī)則配置匹配成功后,構(gòu)建的組織推單記錄列表 */ private static List<OrganizationPushOrderRecordEntity> orgPushOrderRecords = new CopyOnWriteArrayList<>(); public void addOrgPushOrder(final OrganizationPushOrderRecordEntity organizationPushOrderRecord) { orgPushOrderRecords.add(organizationPushOrderRecord); } }
定義對象的時候,我對可能不安全的類加上了static,當(dāng)時考慮到ArrayList是線程不安全的,所以特意使用了CopyOnWriteArrayList。
但沒成想,這里的list是被實例之間共享的,這樣多個實例都可以訪問到這個list,那么就不是我想要的結(jié)果了,我想要的是彼此不可見。
好基礎(chǔ)的bug啊,算是補(bǔ)上了。
以上就是java對象中什么時候適合用static修飾符踩坑解決記錄的詳細(xì)內(nèi)容,更多關(guān)于java對象static修飾符的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java對list<Object>進(jìn)行手動分頁實現(xiàn)
本文主要介紹了java對list<Object>進(jìn)行手動分頁實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07SpringbootJPA分頁 PageRequest過時的替代方法
這篇文章主要介紹了SpringbootJPA分頁 PageRequest過時的替代方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06SpringBoot項目找不到j(luò)avax.servlet.Filter的問題及解決
這篇文章主要介紹了SpringBoot項目找不到j(luò)avax.servlet.Filter的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07教你通過B+Tree平衡多叉樹理解InnoDB引擎的聚集和非聚集索引
大家都知道B+Tree是從二叉樹演化而來,在這之前我們來先了解二叉樹、平衡二叉樹、平衡多叉樹,這篇文章主要介紹了通過B+Tree平衡多叉樹理解InnoDB引擎的聚集和非聚集索引,需要的朋友可以參考下2022-01-01SpringBoot+Ajax+redis實現(xiàn)隱藏重要接口地址的方法
這篇文章主要介紹了SpringBoot+Ajax+redis實現(xiàn)隱藏重要接口地址,本篇文章主要講訴使用SpringBoot項目配合Ajax和redis實現(xiàn)隱藏重要接口地址,這里我以隱藏秒殺地址為例,需要的朋友可以參考下2024-03-03springboot @WebFilter注解過濾器的實現(xiàn)
這篇文章主要介紹了springboot @WebFilter注解過濾器的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03