Java內(nèi)部類總結(jié)

一、內(nèi)部類有幾種?

內(nèi)部類分為成員內(nèi)部類、靜態(tài)嵌套類、方法內(nèi)部類、匿名內(nèi)部類。
幾種內(nèi)部類的共性:
A、內(nèi)部類仍然是一個獨立的類,在編譯之后會內(nèi)部類會被編譯成獨立的.class文件,但是前面冠以外部類的類命和$符號。
B、內(nèi)部類不能用普通的方式訪問。內(nèi)部類是外部類的一個成員,因此內(nèi)部類可以自由地訪問外部類的成員變量,無論是否是private的。

二、成員內(nèi)部類

定義

    class Outer {
        class Inner{}
    }

編譯上述代碼會產(chǎn)生兩個文件:Outer.class和Outer$Inner.class。
成員內(nèi)部類內(nèi)不允許有任何靜態(tài)聲明!下面代碼不能通過編譯。

    class Inner{
        static int a = 10;
    }

用法

能夠訪問成員內(nèi)部類的唯一途徑就是通過外部類的對象!

1. 從外部類的非靜態(tài)方法中實例化內(nèi)部類對象

    class Outer {
        private int i = 10;
        public void makeInner(){
            Inner in = new Inner();
            in.seeOuter();
        }
        class Inner{
            public void seeOuter(){
                System.out.print(i);
            }
        }
    }

表面上,我們并沒有創(chuàng)建外部類的對象就實例化了內(nèi)部類對象,和上面的話矛盾。事實上,如果不創(chuàng)建外部類對象也就不可能調(diào)用makeInner()方法,所以到頭來還是要創(chuàng)建外部類對象的。
你可能試圖把makeInner()方法修飾為靜態(tài)方法,即static public void makeInner()。這樣不創(chuàng)建外部類對象就可以實例化內(nèi)部類了!但是在一個靜態(tài)方法里能訪問非靜態(tài)成員和方法嗎?顯然不能。它沒有this引用。沒能跳出那條規(guī)則!但是如果在這個靜態(tài)方法中實例化一個外部類對象,再用這個對象實例化內(nèi)部類呢?完全可以!也就是下一條的內(nèi)容。

2. 從外部類的靜態(tài)方法中實例化內(nèi)部類對象

    class Outer {
        private int i = 10;
        class Inner{
            public void seeOuter(){
                System.out.print(i);
            }
        }    
        public static void main(String[] args) {
            Outer out = new Outer();
            Outer.Inner in = out.new Inner();
            //Outer.Inner in = new Outer().new Inner(); 可以代替前兩行
            in.seeOuter();
        }
    }

對比一下:在外部類的非靜態(tài)方法中實例化內(nèi)部類對象是普通的new方式:Inner in = new Inner();
在外部類的靜態(tài)方法中實例化內(nèi)部類對象,必須先創(chuàng)建外部類對象:Outer.Inner in = new Outer().new Inner();

3. 內(nèi)部類的this引用

普通的類可以用this引用當(dāng)前的對象,內(nèi)部類也是如此。但是假若內(nèi)部類想引用外部類當(dāng)前的對象呢?用“外部類名”.this;的形式,如下例的Outer.this。

    class Outer {
        class Inner{
            public void seeOuter(){
                System.out.println(this);
                System.out.println(Outer.this);
            }
        }
    }

4. 成員內(nèi)部類的修飾符

對于普通的類,可用的修飾符有final、abstract、strictfp、public和默認的包訪問。
但是成員內(nèi)部類更像一個成員變量和方法。
可用的修飾符有:final、abstract、public、private、protected、strictfp和static。
一旦用static修飾內(nèi)部類,它就變成靜態(tài)內(nèi)部類了。

三、方法內(nèi)部類

定義

顧名思義,把類放在方法內(nèi)。

    class Outer {
        public void doSomething(){
            class Inner{
                public void seeOuter(){
                }
            }    
        }
    }

用法

1. 方法內(nèi)部類只能在定義該內(nèi)部類的方法內(nèi)實例化,不可以在此方法外對其實例化

2. 方法內(nèi)部類對象不能使用該內(nèi)部類所在方法的非final局部變量

因為方法的局部變量位于棧上,只存在于該方法的生命期內(nèi)。當(dāng)一個方法結(jié)束,其棧結(jié)構(gòu)被刪除,局部變量成為歷史。但是該方法結(jié)束之后,在方法內(nèi)創(chuàng)建的內(nèi)部類對象可能仍然存在于堆中!例如,如果對它的引用被傳遞到其他某些代碼,并存儲在一個成員變量內(nèi)。正因為不能保證局部變量的存活期和方法內(nèi)部類對象的一樣長,所以內(nèi)部類對象不能使用它們。
下面是完整的例子:

    class Outer {
        public void doSomething(){
            final int a =10;
            class Inner{
                public void seeOuter(){
                    System.out.println(a);
                }
            }   
            Inner in = new Inner();
            in.seeOuter(); 
        }
        public static void main(String[] args) {
            Outer out = new Outer();
            out.doSomething();
        }
     }

3. 方法內(nèi)部類的修飾符

與成員內(nèi)部類不同,方法內(nèi)部類更像一個局部變量。
可以用于修飾方法內(nèi)部類的只有final和abstract。

4. 靜態(tài)方法內(nèi)的方法內(nèi)部類

靜態(tài)方法是沒有this引用的,因此在靜態(tài)方法內(nèi)的內(nèi)部類只能訪問外部類的靜態(tài)成員。

四、匿名內(nèi)部類

顧名思義,沒有名字的內(nèi)部類。表面上看起來它們似乎有名字,實際那不是它們的名字。

A. 繼承式的匿名內(nèi)部類

    class Car {
        public void drive(){
            System.out.println("Driving a car!");
        }
    }
    
    class Test{
        public static void main(String[] args) {
            Car car = new Car(){
                public void drive(){
                    System.out.println("Driving another car!");
                }
            };
            car.drive();
        }
    }

結(jié)果輸出了:Driving another car! Car引用變量不是引用Car對象,而是Car匿名子類的對象。
建立匿名內(nèi)部類的關(guān)鍵點是重寫父類的一個或多個方法。再強調(diào)一下,是重寫父類的方法,而不是創(chuàng)建新的方法。因為用父類的引用不可能調(diào)用父類本身沒有的方法!創(chuàng)建新的方法是多余的。簡言之,參考多態(tài)。

B. 接口式的匿名內(nèi)部類

    interface  Vehicle {
        public void drive();
    }
    
    class Test{
        public static void main(String[] args) {
            Vehicle v = new Vehicle(){
                public void drive(){
                    System.out.println("Driving a car!");
                }
            };
            v.drive();
        }
    }

上面的代碼很怪,好像是在實例化一個接口。事實并非如此,接口式的匿名內(nèi)部類是實現(xiàn)了一個接口的匿名類。而且只能實現(xiàn)一個接口。

C. 參數(shù)式的匿名內(nèi)部類

class Bar{
    void doStuff(Foo f){}
}

interface Foo{
    void foo();
}

class Test{
    static void go(){
        Bar b = new Bar();
        b.doStuff(new Foo(){
            public void foo(){
                System.out.println("foofy");
            }
        });
    }
}

五、靜態(tài)嵌套類

從技術(shù)上講,靜態(tài)嵌套類不屬于內(nèi)部類。因為內(nèi)部類與外部類共享一種特殊關(guān)系,更確切地說是對實例的共享關(guān)系。而靜態(tài)嵌套類則沒有上述關(guān)系。它只是位置在另一個類的內(nèi)部,因此也被稱為頂級嵌套類。
靜態(tài)的含義是該內(nèi)部類可以像其他靜態(tài)成員一樣,沒有外部類對象時,也能夠訪問它。靜態(tài)嵌套類只能訪問外部類的靜態(tài)成員和靜態(tài)方法。

    class Outer{
        static class Inner{}
    }
    class Test {
        public static void main(String[] args){
            Outer.Inner n = new Outer.Inner();
        }
    } 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概念介紹 內(nèi)部類在Java中,可以將一個類定義在另一個類里面或者一個方法里面,這樣的類稱為內(nèi)部類。內(nèi)部類是一種非常...
    niaoge2016閱讀 692評論 0 1
  • Java 內(nèi)部類 分四種:成員內(nèi)部類、局部內(nèi)部類、靜態(tài)內(nèi)部類和匿名內(nèi)部類。 1、成員內(nèi)部類: 即作為外部類的一個成...
    ikaroskun閱讀 1,358評論 0 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,734評論 18 399
  • 一:java概述:1,JDK:Java Development Kit,java的開發(fā)和運行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,815評論 0 11
  • 大叔知道我是做什么的。 我是心里咨詢師。而每天我見到的人很多很多,他們時而哭泣,時而憤怒,時而迷茫,我看著這些人的...
    DIDickson閱讀 256評論 0 0

友情鏈接更多精彩內(nèi)容