Java 類中各成分加載順序 和 內存中的存放位置

參加一個筆試,有一個關於類的靜態代碼塊、構造代碼塊、構造函數的執行順序的問題。不太清楚,網上百度了一下。在這裏記錄一下。

一、什麼時候會加載類?
使用到類中的內容時加載:有三種情況
1.創建對象:new StaticCode();
2.使用類中的靜態成員:StaticCode.num=9;  StaticCode.show();
3.在命令行中運行:java StaticCodeDemo

二、類所有內容加載順序和內存中的存放位置:
利用語句進行分析。
1.Person p=new Person("zhangsan",20);
該句話所做的事情:
1.在棧內存中,開闢main函數的空間,建立main函數的變量 p。
2.加載類文件:因爲new要用到Person.class,所以要先從硬盤中找到Person.class類文件,並加載到內存中。
加載類文件時,除了非靜態成員變量(對象的特有屬性)不會被加載,其它的都會被加載。
記住:加載,是將類文件中的一行行內容存放到了內存當中,並不會執行任何語句。---->加載時期,即使有輸出語句也不會執行。
靜態成員變量(類變量) ----->方法區的靜態部分
靜態方法              ----->方法區的靜態部分
非靜態方法(包括構造函數) ----->方法區的非靜態部分
靜態代碼塊 ----->方法區的靜態部分
構造代碼塊 ----->方法區的靜態部分

注意:在Person.class文件加載時,靜態方法和非靜態方法都會加載到方法區中,只不過要調用到非靜態方法時需要先實例化一個對象
,對象才能調用非靜態方法。如果讓類中所有的非靜態方法都隨着對象的實例化而建立一次,那麼會大量消耗內存資源,
所以纔會讓所有對象共享這些非靜態方法,然後用this關鍵字指向調用非靜態方法的對象。


3.執行類中的靜態代碼塊:如果有的話,對Person.class類進行初始化。
4.開闢空間:在堆內存中開闢空間,分配內存地址。
5.默認初始化:在堆內存中建立 對象的特有屬性,並進行默認初始化。
6.顯示初始化:對屬性進行顯示初始化。
7.構造代碼塊:執行類中的構造代碼塊,對對象進行構造代碼塊初始化。
8.構造函數初始化:對對象進行對應的構造函數初始化。
9.將內存地址賦值給棧內存中的變量p。
2.p.setName("lisi");
1.在棧內存中開闢setName方法的空間,裏面有:對象的引用this,臨時變量name
2.將p的值賦值給this,this就指向了堆中調用該方法的對象。
3.將"lisi" 賦值給臨時變量name。
4.將臨時變量的值賦值給this的name。
3.Person.showCountry();
1.在棧內存中,開闢showCountry()方法的空間,裏面有:類名的引用Person。
2.Person指向方法區中Person類的靜態方法區的地址。
3.調用靜態方法區中的country,並輸出。
  注意:要想使用類中的成員,必須調用。通過什麼調用?有:類名、this、super
  
三、靜態代碼塊、構造代碼塊和構造函數的區別
靜態代碼塊:用於給類初始化,類加載時就會被加載執行,只加載一次。
構造代碼塊:用於給對象初始化的。只要建立對象該部分就會被執行,且優先於構造函數。
構造函數:  給對應對象初始化的,建立對象時,選擇相應的構造函數初始化對象。
 創建對象時,三者被加載執行順序:靜態代碼塊--->構造代碼塊--->構造函數
 
//利用代碼進行測試 例題:06--06:StaticCodeDemo.java

  1. class Person  
  2. {  
  3. private String name;  
  4. private int age=0;  
  5. private static String country="cn";  
  6. Person(String name,int age)  
  7. {  
  8. this.name=name;  
  9. this.age=age;   
  10. }  
  11. static  
  12. {  
  13. System.out.println("靜態代碼塊被執行");  
  14. }  
  15. { System.out.println(name+"..."+age);}  
  16. public void setName(String name)  
  17. {  
  18. this.name=name;  
  19. }  
  20. public void speak()  
  21. {  
  22. System.out.println(this.name+"..."+this.age);  
  23. }  
  24. public static void showCountry()  
  25. {  
  26. System.out.println("country="+country);  
  27. }  
  28. }  
  29. class StaticDemo  
  30. {  
  31. static  
  32. {  
  33. System.out.println("StaticDemo 靜態代碼塊1");  
  34. }  
  35. public static void main(String[] args)  
  36. {  
  37. Person p=new Person("zhangsan",100);  
  38. p.setName("lisi");  
  39. p.speak();  
  40. Person.showCountry();  
  41. }  
  42. static  
  43. {  
  44. System.out.println("StaticDemo 靜態代碼塊2");  
  45. }   
  46. }  


輸出結果:
 StaticDemo 靜態代碼塊1
 StaticDemo 靜態代碼塊2
 靜態代碼塊被執行
 null...0   //構造代碼塊
 lisi...100 //speak()
 country=cn //showCountry()
發佈了45 篇原創文章 · 獲贊 122 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章