糾結了很久的一個問題, 內部類和靜態內部類在使用上有啥區別

ZZ100861122發表於2020-12-26

文章目錄

    歷史資訊
    對比

歷史資訊

Java中的內部類是在Jdk1.1版本之後增加的,內部類是Java語言中一個比較重要的概念,如果能把內部類運用好,那麼會明顯增強Java程式的靈活性。
內部類無論是靜態還是非靜態, 本質上都是寫在內部的一個類, 比如下面程式碼

public class Demo {

class Test {
    
}

}

1
2
3
4
5
6

對比

我們都知道Java的類是有封裝性的, 比如我們將一個屬性或者方法寫成是private修飾的, 那麼只能在類的內部進行使用, 外部是無法使用的
所以, 內部類是可以訪問私有屬性和私有方法的, 但是要清楚靜態和非靜態對私有的欄位訪問還是有差距的, 後面講到哈~

第一,內部類可以訪問其所在類的屬性(包括所在類的私有屬性)

public class Demo {

private static String name = "bike"; //外部類的私有靜態變數
private int age = 10;    //外部類的私有屬性

private void play() {   //外部類的私有方法
    System.out.println("play");
}

class Stu {   //內部類
    
    int age = 20;
    public void print() {
        System.out.println(age);  //20
        System.out.println(this.age);   //20
        //通過外部類名加this可以訪問外部類的所有屬性和方法
        System.out.println(Demo.this.age);   //10
        Demo.this.play();  //外部類的play方法
        Stu stu = Demo.this.new Stu();  //初始化內部類例項
        System.out.println(Demo.name);   //訪問外部類的私有靜態變數
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

第二, 可以在方法體內定義一個內部類,方法體內的內部類可以完成一個基於虛方法形式的回撥操作,看一個例子:

private Stu play() {   //外部類的私有方法
    System.out.println("play");
    class Tea extends Stu {
        @Override
        public void print() {
            super.print();
            System.out.println("我是Tea執行的");
        }
    }
    return new Tea();
}

1
2
3
4
5
6
7
8
9
10
11

第三, 內部類不能定義static元素,看一個例子:
在這裡插入圖片描述
第四, 內部類可以多巢狀,看一個例子:
也就是說內部類裡可以有內部類

第五, 例項化一個內部類需要先例項化外部類

public static void main(String[] args) {
    //例項化一個非靜態內部類的時候需要先例項化外部類, 也就是需要例項化倆個物件
    Stu stu = new Demo().new Stu();
}

1
2
3
4

對於靜態內部類, 其實我們都知道一個類的靜態屬性欄位, 都會在這個類在載入的時候就載入出來, 隨著類物件一起出生, 將他們存放在方法區中, 所以本質上來說內部類還是屬於例項的, 所以在例項化內部類的時候需要先例項化外部類, 而靜態內部類就是屬於類的, 那麼他嚴格來說已經不算是一個完全的內部類
所以對於靜態內部類, 他除了是寫在內部類的位置上, 可以訪問外部類靜態的的私有屬性和欄位, 其餘和外部類沒有任何區別
也就是說靜態內部類是一個還是比較高階的頂級類

第一, 靜態內部類可以有靜態屬性和方法, 當然也可以有普通的

static class Per {
    static String name = "listen";
    int age = 30;
    
    public static void print() {
        System.out.println(name);
    }
}

1
2
3
4
5
6
7
8

第二, 靜態類可以訪問外部類的私有靜態變數, 普通屬性不能訪問了

static class Per {
    static String name = "listen";
    int age = 30;

    public static void print() {
        System.out.println(name);
        //靜態內部類訪問外部類的私有靜態屬性
        System.out.println(Demo.name);
        //靜態內部類訪問外部類的普通屬性  
        System.out.println(Demo.this.age);  //報錯了
    }
}

1
2
3
4
5
6
7
8
9
10
11
12

第三, 例項化一個靜態內部類只需要例項化一個物件

public static void main(String[] args) {

    Demo.Per per = new Demo.Per();
}

相關文章