天天看點

【Java入門提高篇】Day9 Java内部類——靜态内部類

  今天來說說Java中的最後一種内部類——靜态内部類

  所謂的靜态内部類,自然就是用static修飾的内部類,那用static修飾過後的内部類,跟一般的内部類相比有什麼特别的地方呢?

  首先,它是靜态的,這就意味着它的建立不依賴于外部類,建立内部類的執行個體不需要像普通内部類一樣先建立外部類執行個體才能建立。

  其次,有優勢必然有劣勢,它不能像普通内部類一樣無限制的通路外部類的方法和成員變量,隻能通路靜态成員變量和靜态方法。

  話不多說,先來看個栗子:

public class StaticInnerClass {

    //外部類的非靜态成員
    private int numA = 1;

    //外部類的靜态成員
    private static int numB = 2;

    //靜态内部類
    static class Inner {
        //内部類的非靜态成員
        private int numC = 3;
        //内部類的靜态成員
        private static int numD = 4;

        public void printInner(){
            System.out.println("printInner");
            System.out.println(numB);//通路外部類的靜态成員
            System.out.println(numC);//通路内部類的非靜态成員
            System.out.println(numD);//通路内部類的靜态成員
        }
    }

    //外部類的普通成員方法
    public void printOuter(){
        System.out.println("printOuter");
    }

    public static void main(String[] args) {
        StaticInnerClass outer = new StaticInnerClass();
        outer.printOuter();
        Inner inner = new StaticInnerClass.Inner();
        inner.printInner();
        System.out.println(StaticInnerClass.numB);
        System.out.println(Inner.numD);
    }
}           

複制

  輸出如下:

printOuter
printInner
2
3
4
2
4           

複制

  看起來,内部類跟外部類的使用上是差不多的,更像是一個暫存在外部類中的一個類,跟外部類并沒有什麼太多本質上的聯系,但是建立的時候需要使用Outer.Inner的方式來定義,就像給類加了一個命名空間一樣。

  再舉個栗子來看看靜态内部類和非靜态内部類的差別:(知乎上看到的一段話,覺得比喻比較形象)

如果把類比喻成雞蛋,内部類為蛋,,外部類是蛋殼。那麼靜态類相當于熟雞蛋,就算蛋殼破碎(外部類沒有執行個體化),蛋黃依然完好(内部類可以執行個體化);而非靜态類相當于生雞蛋,蛋殼破碎(無執行個體化),蛋黃也會跟着xx(不能執行個體化)。

  至于原因?其實就是因為非靜态内部類中儲存有外部類的指針,是以可以無限制通路外部類的所有屬性,而靜态内部類則沒有,是以靜态内部類無法通路外部類的非靜态成員和方法,僅僅是借用一下它的殼而已。

  再來看一個栗子:

public class Caculate {

    //定義一個pair類來将兩個數捆綁
    static class Pair{
        private int first;
        private int second;

        public Pair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public int getFirst() {
            return first;
        }

        public int getSecond() {
            return second;
        }
    }

    //擷取一個int數組中的最大和最小值
    public static Pair getMaxMin(int[] values){
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for (int i:values){
            if (min > i) min = i;
            if (max < i) max = i;
        }
        return new Pair(min,max);
    }

    public static void main(String[] args){
        int[] list = {1,3,5,2,77,23,25};
        Caculate.Pair pair = Caculate.getMaxMin(list);
        System.out.println(pair.getFirst());
        System.out.println(pair.getSecond());
        System.out.println(pair.first);
        System.out.println(pair.second);
    }
}           

複制

  這裡getMaxMin裡需要一次傳回兩個值,是以用了一個Pair類來将兩個數捆綁到一起,而因為這個類隻在Caculate類中使用,而且兩者并沒有依賴關系,是以這裡使用靜态内部類是最合适的。

  靜态内部類還有很多适用的場景,這就需要大家在今後的使用中慢慢體會了。

  至此,本篇講解完畢,歡迎大家繼續關注。