【Java基礎】內部類


非靜態內部類不能擁有靜態變量 為什么

下面這段代碼,如果Lazyholder沒有static修飾,則編譯不過

class Singleton2 {
    private static class LazyHolder {
        private static Singleton2 singleton;
    }
    public Singleton2 getInstance() {
        return LazyHolder.singleton;
    }
}

"非靜態內部類不能擁有靜態變量" ,可以這樣理解,因為JVM類加載的順序為:

 

java根據需要在運行時把字節碼載入到內存,它分三個步驟:

1、加載:類加載器查找到字節碼(.class文件)並根據這些字節碼創建一個Class對象;

2、鏈接:驗證類中的字節碼,為靜態域分配存儲空間,需要的話同時解析這個類其它類的所有引用;

3、初始化:當類的靜態方法(構造器是特殊的靜態方法)或者非常數靜態域(即不是編譯器常量)被首次引用時,執行靜態初始化塊和初始化靜態數據。

然后才能執行對象創建

 

如果LazyHolder沒有static,則本質上,它其實是Singleton2的非靜態成員,則他必須在Singleton2對象創建之后才會進行加載,然而問題在於,另一方面根據JVM的加載順序,static 的singleton變量又必須在LazyHolder對象存在之前完成加載,這就矛盾了。

 

靠,上面的是昨天寫的,今天突然看不懂了。我想了想,更簡單的理解是:

      靜態變量是要能夠直接用類名.靜態變量的方式來訪問的,在上面這個例子中,實際上就是Singleton2.LazyHolder.singleton,是這樣去訪問,但是如果LazyHolder不是靜態類,那問題就來了,你會發現singleton無法被訪問了!因為Singleton.LazyHolder就已經不合法了,根本沒法往下走。嗯,我覺得我自己的理解比網上查到的靠譜多了

 

什么是匿名內部類

實際上匿名內部類是對下面這種寫法的簡化

public class InnerClassLearn {
    class MyThread extends Thread {
        private int i = 11;
        public int value() {return i;}
    }
    public Thread thread() {return new MyThread();}

    public static void main(String[] args) {
        Thread thread = new InnerClassLearn().thread();
    }
}

用匿名內部類的方式重寫上面的代碼:

public class InnerClassLearn {
    
    public Thread thread() {
        return new Thread() {
            private int i = 11;
            public int value() {return i;} };
    }
    
    public static void main(String[] args) {
        Thread thread = new InnerClassLearn().thread();
    }
}

其中紅色部分就是一個繼承於 Thread類的匿名內部類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM