jvm之類加載器(1)

gg1993 8年前發布 | 13K 次閱讀 JVM Java開發

來自: http://www.cnblogs.com/think-in-java/p/5178383.html

首先我們先看一個示例程序:

package com.tfdd.test;

/**
 * @desc 類加載校驗
 * @author chenqm 
 * @date 2016年2月2日
 */
class Singleton{
    private static Singleton singleton = new Singleton();
    public static int count1 ;
    public static int count2 = 0;

    private Singleton(){
        count1++;
        count2++;
    }

    public static Singleton getInstance(){

        return singleton;
    }

}
public class SingletonTest {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        System.out.println(singleton.count1);
        System.out.println(singleton.count2);
    }
}

猜猜輸出的結果是什么?據說80%的java程序猿都會犯的錯誤!

10

就是這樣一個結果,我們先不說為什么。接著講我們的類加載器.

類的加載大致分為三個部分:加載,連接,初始化。

加載 :查找并加載類的二進制數據

連接 :1.驗證(確保被加載類的準確性) 2.準備(為類的靜態變量分配內存,并將其初始化為默認值) 3.解析(將類中的符號引用轉化為直接引用)

初始化 :為類的靜態變量賦予正確的初始值(即賦上我們給出的值)

然后我們再看看java程序對類的使用方式:主動使用和被動使用。請注意下面我說的這句話

所有的JAVA虛擬機實現必須在每個類或接口被JAVA程序“首次主動使用”時才初始化他們。

那么什么叫主動使用?基本上分為6種情況:

--創建類的實例

--訪問某個類或接口的靜態變量,或者對該靜態變量賦值

--調用類的靜態方法

--反射

--初始化一個類的子類

--java虛擬機啟動時被標明為啟動類的類

了解了這些知識之后,我現在來回答之前的問題,

Singleton.getInstance(); 調用了類的靜態方法,符合首次主動使用該類的情況!那么我們進入初始化階段。
初始化已經屬于類加載的第三步了,在第二步的連接的準備部分,已經賦過一次默認值了。所以應該是這樣一個過程:
1.singleton = null;count1=0;count1=0 2.singleton = new Singleton(); 此時執行構造函數,結果為count0=1;count1=1 3.count0沒有被我們賦值跳過初始化,count1賦值為0所以結果為count0=1;count1=0 (*注意) 類的靜態變量賦值的順序是按照代碼的書寫的順序執行的。
修改代碼如下:
package com.tfdd.test;

/**

  • @desc 類加載校驗
  • @author chenqm
  • @date 2016年2月2日 */ class Singleton{ public static int count1 ; public static int count2 = 0; private static Singleton singleton = new Singleton();

    private Singleton(){

     count1++;
     count2++;
    

    }

    public static Singleton getInstance(){

     return singleton;
    

    }

} public class SingletonTest { public static void main(String[] args) { Singleton singleton = Singleton.getInstance(); System.out.println(singleton.count1); System.out.println(singleton.count2); } }</pre>

輸出結果為

1

1

證明賦值的順序是根據代碼書寫的先后順序執行的!

</div>

 本文由用戶 gg1993 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!