java ClassLoader static

 

package init;

class Person {

    private static Person person = new Person(); public static int count2 = 5; public static int count1;

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

    public static Person getInstance()
    {
        return person;
    }

}

public class Testsingleton {
    public static void main(String[] args) {
        System.out.println("count1: " + Person.count1);
        System.out.println("count2: " + Person.count2);
    }

}

 


Output:
count1: 1
count2: 5

緣由:
ClassLoader java

類在執行以前會執行三個步驟:優化

1.類的加載:查找並加載類的二進制數據,把對應的class文件加載到內存spa

2.鏈接code

     2.1. 驗證:確保被加載的類的正確性(主要防止噁心的class文件被加載)blog

     2.2. 準備:爲類的靜態變量分配內存,並將其初始化爲默認值接口

     2.3. 解析:把類中的符合引用轉換爲直接引用內存

3.初始化:爲類的靜態變量賦予正確的初始值get

 

發現其中步驟2.2和3提到了關鍵字靜態變量,重點關注這兩步,2.2的結果會致使爲靜態變量編譯器

person,count1,count2分配內存並賦值(默認值)虛擬機

person=null;

count1=count2=0

 

到步驟3,初始化時會爲靜態變量賦予正確的值,那麼何時纔會進行初始化呢?

     全部的java虛擬機實現必須在每個類或接口被java程序「首次主動使用」時才初始化 

java對類的使用方式分爲:主動使用,被動使用

主動使用有六種:(除這6種外,其餘都是被動使用)

一、建立類的實例
二、訪問某個類或接口的靜態變量或對該靜態變量賦值
三、調用類的靜態方法
四、反射
五、初始化類的子類
六、java虛擬機啓動時被標註位啓動類的類

即在執行main方法時會爲靜態變量賦值,若是有多個靜態變量,按照自上而下的順序(編譯器會優化,與代碼書寫的順序會不一致)
爲person變量初始化時後count1=1;count2=1;

public static int count2 = 5;執行後,count2=5

驗證:

package init;

class Person {

    public static int count2 = 5; private static Person person = new Person(); public static int count1;

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

    public static Person getInstance()
    {
        return person;
    }

}

public class Testsingleton {
    public static void main(String[] args) {
        System.out.println("count1: " + Person.count1);
        System.out.println("count2: " + Person.count2);
    }

}

Output:
count1: 1
count2: 6

http://longpo.iteye.com/blog/2217113

相關文章
相關標籤/搜索