當前位置:
首頁 > 知識 > 你知道么?static關鍵字有5種用法

你知道么?static關鍵字有5種用法


摘要: 本文帶你領略Java實際開發中static的5種用法。

說到static,靜態變數和靜態方法大家隨口就來,因為他們在實際開發中應用很廣泛,但他們真正在使用的時候會存在很多問題,而且它的使用不只那兩種:

1.靜態變數。

2.靜態方法。

3.靜態代碼塊。

4.靜態內部類。

5.靜態導入。

接下來我們看一下這些用法。

1.靜態變數

靜態變數屬於類,內存中只有一個實例,當類被載入,就會為該靜態變數分配內存空間,跟 class 本身在一起存放在方法區中永遠不會被回收,除非 JVM 退出。(方法區還存哪些東西可以看看:Java虛擬機運行時數據區域)靜態變數的使用方式:【類名.變數名】和【對象.變數名】。

【實例】實際開發中的日期格式化類SimpleDateFormat會經常用到,需要的時候會new一個對象出來直接使用,但我們知道頻繁的創建對象不好,所以在DateUtil中直接創建一個靜態的SimpleDateFormat全局變數,直接使用這個實例進行操作,因為內存共享,所以節省了性能。但是它在高並發情況下是存在線程安全問題的。SimpleDateFormat線程安全問題代碼復現:

你知道么?static關鍵字有5種用法

你知道么?static關鍵字有5種用法

運行後會報java.lang.NumberFormatException: multiple points或For input string: ""等錯誤,其實你會發現volatile修飾也沒用,關於volatile關鍵字博主會在後續文章做介紹,上面代碼運行報錯的原因是多線程都去操作一個對象,(本圖來自於:關於 SimpleDateFormat 的非線程安全問題及其解決方案):

你知道么?static關鍵字有5種用法

解決辦法:1.使用私有的對象。2.加鎖。3.用ThreadLocal。

你知道么?static關鍵字有5種用法

上圖兩圖是使用私有對象和ThreadLocal解決高並髮狀態的圖解。博主給出使用私有的對象和加鎖兩種實現代碼:

你知道么?static關鍵字有5種用法

本文給出的兩種方式都會對性能有不同程度的影響。推薦使用ThreadLocal,因為它的性能最好,讀者可以嘗試自己實現。

2.靜態方法

靜態方法和非靜態方法一樣,都跟class 本身在一起存放在內存中,永遠不會被回收,除非 JVM 退出,他們使用的區別的一個方面是非static方法需要實例調用,static方法直接用類名調用。

【實例一】單例模式,它提供了一種創建對象的最佳方式,保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

你知道么?static關鍵字有5種用法

靜態的方法不必實例化就能直接使用,用法方便,不用頻繁的為對象開闢空間和對象被回收,節省系統資源。是不是相較之下覺得static用的比較爽呢?但是他也會帶來一些問題:

【實例二】一般工具類中的方法都寫成static的,比如我們要實現一個訂單導出功能,代碼如下:

你知道么?static關鍵字有5種用法

為什麼orderService會是null?原因不是spring沒注入,而是static方法給它"清空"了。解決方案一:@PostConstruct,它修飾的方法會在伺服器載入Servlet時執行一次,代碼如下:

你知道么?static關鍵字有5種用法

每個工具類都要去加上@PostConstruct註解,代碼重複性高。思考我們可不可以直接從spring容器中獲取Bean實例?解決方案二:ApplicationContextAware。當一個類實現了ApplicationContextAware介面之後,這個類就可以方便獲得ApplicationContext中的所有bean。換句話說,就是這個類可以直接獲取spring配置文件中,所有有引用到的bean對象。

你知道么?static關鍵字有5種用法

把他放入spring容器中:

你知道么?static關鍵字有5種用法

最終,原來的代碼可以簡化到如下:

你知道么?static關鍵字有5種用法

3.靜態代碼塊

我們其實在工作中一直用到的代碼塊,所謂代碼塊是指使用「{}」括起來的一段代碼。其中靜態代碼塊只執行一次,構造代碼塊在每次創建對象是都會執行。根據位置不同,代碼塊可以分為四種:普通代碼塊、構造塊、靜態代碼塊、同步代碼塊。ref:Java中普通代碼塊,構造代碼塊,靜態代碼塊區別及代碼示例。

【實例】因為JVM只為靜態分配一次內存,在載入類的過程中完成靜態變數的內存分配。所以實際工作中我們可以使用靜態代碼塊初始化一些不變的屬性:

你知道么?static關鍵字有5種用法

但是靜態代碼塊和靜態變數初始化有什麼關係?在上文的單例模式中,我們使用了靜態代碼塊來創建對象,為何那那樣寫?我在網上看到了這樣一段代碼:

你知道么?static關鍵字有5種用法

上面的結果是10還是20?如果存在多個代碼塊呢?

你知道么?static關鍵字有5種用法

測試過後你會發現兩個答案結果都是20。

因為其實public static int _i = 10; 和如下代碼:

你知道么?static關鍵字有5種用法

是沒有區別的,他們在編譯後的位元組碼完全一致(讀者可以使用javap -c命令查看位元組碼文件),所以兩個例子的結果就是最後一次賦值的數值。

4.靜態內部類

在定義內部類的時候,可以在其前面加上一個許可權修飾符static,此時這個內部類就變為了靜態內部類。

【實例一】前文中寫靜態方法時的實例一,我們用了static塊初始化單例對象,這樣做有一個弊端,在調用單例其他方法時也會初始化對象,現在我們只希望在調用getInstance方法時初始化單例對象,要怎麼改進呢?因為餓汗式寫法性能不太好,所以最終單例模式優化到如下:

你知道么?static關鍵字有5種用法

【實例二】博主在內部類的實際開發中應用不多,但有時候還真不能沒有它,比如LinkedList使用了如下靜態內部類:

你知道么?static關鍵字有5種用法

其實在數據結構中我們把next和prev稱為前後節點的指針,HashMap內部也使用了靜態內部類Entry的數組存放數據。為了加深理解,讀者可以親自運行以下的代碼來體會一下靜態內部類。

你知道么?static關鍵字有5種用法

實際中的應用可以看看:SpringMvc 靜態內部類 封裝請求數據,在這裡我們來總結一下靜態內部類:

1.加強代碼可讀性。如:StaticInternal.InnerStaticClass inner = new StaticInternal.InnerStaticClass();

2.多個外部類的對象可以共享同一個靜態內部類的對象。

3.靜態內部類無需依賴於外部類,它可以獨立於外部對象而存在。因為靜態類和方法只屬於類本身,並不屬於該類的對象,更不屬於其他外部類的對象。

5.靜態導入

靜態導入是JKD1.5後新加的功能,一般不怎麼常用,了解即可。有時候面試答出來這個會讓別的覺得你熱愛技術。

【實例】 回想一下,我們以前是不是這樣寫獲取隨機數:

你知道么?static關鍵字有5種用法

Math出現的次數太多了,可以簡化嗎?現在我們可以直接使用靜態導入來寫,如下

你知道么?static關鍵字有5種用法

是不是方便了許多?但別著急偷懶,因為使用它過多會導致代碼可讀性差:

你知道么?static關鍵字有5種用法

或許你知道PI是Math類的方法,那bitCount是哪個類的方法呢?所以盡量避免使用static導入,實在要導入的話,去掉*號通配符,直接寫成:java.lang.Integer.bitCount。

博主是個普通的程序猿,水平有限,文章難免有錯誤,歡迎犧牲自己寶貴時間的讀者,就本文內容直抒己見,我的目的僅僅是希望對讀者有所啟發。


學習Java的同學注意了!!!

學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入Java學習交流群495273252,我們一起學Java!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Java團長 的精彩文章:

關於面試!(面試篇)
溫水裡的程序員,技術將成為溫水——學習分享
深入JVM虛擬機之全書腦圖

TAG:Java團長 |

您可能感興趣

Google Adwords 關鍵字工具怎麼用?
關鍵詞:Snapseed
OpenStack關鍵技術系列:Libvirt基礎知識
42年數據分析,Teradata這次關鍵字是「任意」?
VBScript 關鍵字
George Keburia|中性美是他品牌的關鍵詞,他跟Vetements創始人來自一個地方
美國夢?Calvin Klein用50個關鍵詞和一場秀嘗試回答
演算法channel關鍵詞和文章索引
新欄目上線,三個關鍵詞:Global, Inspiring, Weekly | TechBoard
eBay賣家需知曉的有關eBay Store調整的幾個關鍵信息更新
關於Hubert de Givenchy先生的10個關鍵詞。
8大關鍵問題 讓你全面了解Social Lending 蜂巢星球
關於Hubert de Givenchy先生的10個關鍵詞
Pinteres搜索引擎優化,關鍵詞很重要
TOP1.2 關鍵績效指標 Key Performance Indicator
Twitter進行關鍵詞審查
NYPD:掌握很多關於Weinstein的關鍵證據,準備逮捕
Jumia官方回應回款問題:自查payoneer綁定問題,妥投時間很關鍵
iPhone自帶的指南針get:關鍵時刻能救命!
OpenStack關鍵技術系列:最全OpenStack知識科普