一、引言
說實話,此部分知識是在當初學C#基礎的時候學到的,起初就記得有這么回事,后來學Java的時候對於基礎跳過去很多,最近項目上遇到了一個問題,最終問題當然解決了,解決后想到了類中各模塊加載順序這個知識點,當結果與理論此時相互印證一番后,對此知識豁然開朗,也更清晰。
二、問題由來
一個類Test交給Spring進行管理,但是此類通過XML的形式進行配置的,在Test類中利用@Autowired注入了使用@Service注解的Call,private Call call,我在Test類的構造函數中使用了call的某個方法,結果報 空指針問題,起初我的想法是通過XML配置的類不能使用使用注解的類,但是后來想想又覺得肯定不會這樣啊,2種方式肯定可以共同使用啊,調試后發現原因:構造函數是一個類中除開靜態資源部分最先執行的模塊。其他非靜態模塊肯定在他之后進行初始化,所以在構造函數中調用其他非靜態資源,肯定會報空指針異常。
三、舉例說明
下面是我簡化問題后寫的一個小demo,以此相互印證:
1. 一個普通的java類Person,Animal類
public class Person { public Person() { System.out.println("初始化了Peron類"); } }
public class Animal { public Animal() { System.out.println("Animao run..."); } }
2. 一個Man類,引用了Person。
public class Man { static { System.out.println("靜態方法運行了。。。"); } private Person person = new Person(); private static Animal animal = new Animal(); public Man() { System.out.println("3. Man構造函數運行了。。。"); } }
其中包含:靜態方法塊(同C#的靜態構造函數)、全局變量、構造函數。
3. 調用Man的類
public class MyTest { public static void main(String[] args) { Man man=new Man(); } }
四、結果與結論
想想執行結果會是神馬?
思路:
1. 靜態的變量因為是全局的,所以肯定是最早進行初始化的,其次才是非靜態的。
2. 構造函數優先全局變量。
所以執行后的順序應該是
1. 靜態方法塊 2. 靜態全局變量 3. 成員變量 4. 構造函數