1. 程式人生 > >關於java的類例項化的先後順序

關於java的類例項化的先後順序

      最近有同事在部署一箇舊系統的時候遇到問題,在本地部署是沒事的,但一到正式線上伺服器就報錯。報錯的大概意思就是某個類裡面的一個靜態變數為空導致出現空指標異常。為了幫忙解決這個問題,我再詳細地深入程式碼,然後模擬實際情況建立如下類:

1.定義了一個載入配置檔案的類Test1,使用spring註解@Service來例項化這個類。


2.定義了一個final的工具類Test2,然後在這個類裡面新增靜態變數型別為Test1的test1。使用spring註解@Service來例項化這個類。


3.定義一個需要獲取Test2裡面的靜態方法類Test3,Test3裡面有靜態變數需要通過Test2的靜態方法賦值。使用spring註解@Service來例項化這個類。


好了,編譯執行之後問題重現如下錯誤nullpointerexception:


那麼要如何解決這個問題呢?這裡首先要解決思路一定要清晰,從問題報錯的地方入手,明顯是靜態變數沒有賦值,那麼為什麼沒有賦值呢?明顯的跟類載入的首先順序有關,也就是說類的靜態變數會優先執行初始化賦值,但這個時候test2尚未例項化。那麼如何解決呢?這裡我提供一種解決辦法,就是通過init方法給靜態變數賦值,如下:


先猜猜執行結果會怎樣,下面將上圖:


從結果來看解決了空指標的問題,讓我們來總結一下:

1.類的靜態變數,靜態程式碼塊和靜態方法等會優先初始化。注意靜態程式碼塊是會有類的構造方法之前執行。

2.如果要把一個bean例項化並賦值給一個靜態變數,需要使用init方法初始化並賦值。

3.一個類裡面的靜態變數或者靜態程式碼塊的執行先後順序是根據在類裡面定義的順序,跟有沒有final等沒有關係。