JavaSE知識點14java內(nèi)部類詳解

內(nèi)部類基礎(chǔ)

  • 1 定義
    將一個類定義在另一個類里面或者一個方法里面诗力,這樣的類稱為內(nèi)部類妻导。
  • 2 分類
    廣泛意義上的內(nèi)部類一般來說包括這四種:
    1)成員內(nèi)部類
    2)局部內(nèi)部類
    3)匿名內(nèi)部類
    4)靜態(tài)內(nèi)部類

四種內(nèi)部類簡介

  • 1 成員內(nèi)部類
    1)成員內(nèi)部類是最普通的內(nèi)部類句携,它的定義為位于另一個類的內(nèi)部,形如下面的形式:
public class Circle {
    private double radius = 0;
    public static int count =1;

    public Circle(double radius) {
        this.radius = radius;
    }
     class Draw {     //內(nèi)部類
        public void drawSahpe() {
            System.out.println(radius);  //外部類的private成員
            System.out.println(count);   //外部類的靜態(tài)成員
        }
    }
}

2)類Draw像是類Circle的一個成員屿衅,所以Draw類稱為成員內(nèi)部類蝎毡,Circle類稱為外部類。
3)成員內(nèi)部類可以無條件訪問外部類的所有成員屬性和方法(包括private和static修飾的)。
4)當成員內(nèi)部類擁有和外部類同名的成員變量或者方法時,會發(fā)生隱藏現(xiàn)象卷扮,即默認情況下訪問的是成員內(nèi)部類的成員荡澎。如果要訪問外部類的同名成員,需要以下面的形式進行訪問:

Circle.this.radius;

5)在外部類中如果要訪問成員內(nèi)部類的成員晤锹,必須先創(chuàng)建一個成員內(nèi)部類的對象摩幔,再通過指向這個對象的引用來訪問:

public class Circle {
    private double radius = 0;
 
    public Circle(double radius) {
        this.radius = radius;
        getDrawInstance().drawSahpe();   //必須先創(chuàng)建成員內(nèi)部類的對象,再進行訪問
    }
     
    private Draw getDrawInstance() {
        return new Draw();
    }
     
    class Draw {     //內(nèi)部類
        public void drawSahpe() {
            System.out.println(radius);  //外部類的private成員
        }
    }
}

6)另一種創(chuàng)建成員內(nèi)部類的語法如下:

public class Circle {
    private double radius = 0;
 
    public Circle(double radius) {
        this.radius = radius;
    }
     
    class Draw {     //內(nèi)部類
        public void drawSahpe() {
            System.out.println("sheep");  
        }
    }
    public static void main(String[] args)  {
        Circle circle = new Circle();
        Draw drow = circle.new Draw();  //必須通過circle對象來創(chuàng)建
    }
}
  • 2 局部內(nèi)部類
    1)局部內(nèi)部類是定義在一個方法或者一個作用域里面的類鞭铆,它和成員內(nèi)部類的區(qū)別在于局部內(nèi)部類的訪問僅限于方法內(nèi)或者該作用域內(nèi)或衡。
public class People{
    public People() {

    }
}
public class Man{
    public Man()
    }
     
    public People getWoman(){
        class Woman extends People{   //局部內(nèi)部類
            int age =0;
        }
        return new Woman();
    }
}

2)局部內(nèi)部類就像是方法里面的一個局部變量一樣焦影,是不能有public、protected封断、private以及static修飾符的斯辰。

  • 3 匿名內(nèi)部類
    1)匿名內(nèi)部類應(yīng)該是平時我們編寫代碼時用得最多的,在編寫事件監(jiān)聽的代碼時使用匿名內(nèi)部類不但方便坡疼,而且使代碼更加容易維護彬呻。
new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
            }
        }

2)匿名內(nèi)部類是唯一一種沒有構(gòu)造器的類。正因為其沒有構(gòu)造器柄瑰,所以匿名內(nèi)部類的使用范圍非常有限闸氮,大部分匿名內(nèi)部類用于接口回調(diào)。匿名內(nèi)部類在編譯的時候由系統(tǒng)自動起名為Outter$1.class教沾。
3)一般來說蒲跨,匿名內(nèi)部類用于繼承其他類或是實現(xiàn)接口,并不需要增加額外的方法授翻,只是對繼承方法的實現(xiàn)或是重寫或悲。

  • 4 靜態(tài)內(nèi)部類
    靜態(tài)內(nèi)部類也是定義在另一個類里面的類,只不過在類的前面多了一個關(guān)鍵字static藏姐。
    2)靜態(tài)內(nèi)部類是不需要依賴于外部類的隆箩,這點和類的靜態(tài)成員屬性有點類似,并且它不能使用外部類的非static成員變量或者方法羔杨,這點很好理解捌臊,因為在沒有外部類的對象的情況下,可以創(chuàng)建靜態(tài)內(nèi)部類的對象兜材,如果允許訪問外部類的非static成員就會產(chǎn)生矛盾理澎,因為外部類的非static成員必須依附于具體的對象。
public class Outter {
    public Outter() {
         
    }

    static class Inner {
        public Inner() {
             
        }
    }

    public static void main(String[] args)  {
        Outter.Inner inner = new Outter.Inner(); // 不需要先創(chuàng)建外部類的實例
    }
}

深入理解內(nèi)部類

  • 1 為什么成員內(nèi)部類可以無條件訪問外部類的成員曙寡?
    1)編譯器會默認為成員內(nèi)部類添加了一個指向外部類對象的引用糠爬。
    2)雖然我們在定義的內(nèi)部類的構(gòu)造器是無參構(gòu)造器,編譯器還是會默認添加一個參數(shù)举庶,該參數(shù)的類型為指向外部類對象的一個引用
    3)從這里也間接說明了成員內(nèi)部類是依賴于外部類的执隧,如果沒有創(chuàng)建外部類的對象,則無法對Outter this&0引用進行初始化賦值户侥,也就無法創(chuàng)建成員內(nèi)部類的對象了镀琉。
  • 2 為什么局部內(nèi)部類和匿名內(nèi)部類只能訪問局部final變量?
public class Test {
    public static void main(String[] args)  {
         
    }
     
    public void test(final int b) {
        final int a = 10;
        new Thread(){
            public void run() {
                System.out.println(a);
                System.out.println(b);
            };
        }.start();
    }
}

1)當test方法執(zhí)行完畢之后蕊唐,變量a的生命周期就結(jié)束了屋摔,而此時Thread對象的生命周期很可能還沒有結(jié)束,那么在Thread的run方法中繼續(xù)訪問變量a就變成不可能了替梨,但是又要實現(xiàn)這樣的效果钓试,怎么辦呢装黑?Java采用了 復制 的手段來解決這個問題。
2)這個過程是在編譯期間由編譯器默認進行弓熏,如果這個變量的值在編譯期間可以確定恋谭,則編譯器默認會在匿名內(nèi)部類(局部內(nèi)部類)的常量池中添加一個內(nèi)容相等的字面量或直接將相應(yīng)的字節(jié)碼嵌入到執(zhí)行字節(jié)碼中。這樣一來硝烂,匿名內(nèi)部類使用的變量是另一個局部變量箕别,只不過值和方法中局部變量的值相等,因此和方法中的局部變量完全獨立開滞谢。
3)既然在run方法中訪問的變量a和test方法中的變量a不是同一個變量串稀,當在run方法中改變變量a的值的話,會出現(xiàn)什么情況狮杨?
4)對母截,會造成數(shù)據(jù)不一致性,這樣就達不到原本的意圖和要求橄教。為了解決這個問題清寇,java編譯器就限定必須將變量a限制為final變量,不允許對變量a進行更改(對于引用類型的變量护蝶,是不允許指向新的對象)华烟,這樣數(shù)據(jù)不一致性的問題就得以解決了。到這里持灰,想必大家應(yīng)該清楚為何 方法中的局部變量和形參都必須用final進行限定了盔夜。

內(nèi)部類的使用場景和好處

  • 1 每個內(nèi)部類都能獨立的繼承一個接口的實現(xiàn),所以無論外部類是否已經(jīng)繼承了某個(接口的)實現(xiàn)堤魁,對于內(nèi)部類都沒有影響喂链。內(nèi)部類使得多繼承的解決方案變得完整,
  • 2 方便將存在一定邏輯關(guān)系的類組織在一起妥泉,又可以對外界隱藏椭微。
  • 3 方便編寫事件驅(qū)動程序
  • 4 方便編寫線程代碼
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市盲链,隨后出現(xiàn)的幾起案子蝇率,更是在濱河造成了極大的恐慌,老刑警劉巖刽沾,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件本慕,死亡現(xiàn)場離奇詭異,居然都是意外死亡悠轩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門攻泼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來火架,“玉大人鉴象,你說我怎么就攤上這事『渭Γ” “怎么了纺弊?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長骡男。 經(jīng)常有香客問我淆游,道長,這世上最難降的妖魔是什么隔盛? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任犹菱,我火速辦了婚禮,結(jié)果婚禮上吮炕,老公的妹妹穿的比我還像新娘腊脱。我一直安慰自己,他們只是感情好龙亲,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布陕凹。 她就那樣靜靜地躺著,像睡著了一般鳄炉。 火紅的嫁衣襯著肌膚如雪杜耙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天拂盯,我揣著相機與錄音佑女,去河邊找鬼。 笑死磕仅,一個胖子當著我的面吹牛珊豹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播榕订,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼店茶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了劫恒?” 一聲冷哼從身側(cè)響起贩幻,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎两嘴,沒想到半個月后丛楚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡憔辫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年趣些,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贰您。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡坏平,死狀恐怖拢操,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舶替,我是刑警寧澤令境,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站顾瞪,受9級特大地震影響舔庶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜陈醒,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一惕橙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧孵延,春花似錦吕漂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至犬钢,卻和暖如春苍鲜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玷犹。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工混滔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人歹颓。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓坯屿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巍扛。 傳聞我的和親對象是個殘疾皇子领跛,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容

  • Java 內(nèi)部類 分四種:成員內(nèi)部類、局部內(nèi)部類撤奸、靜態(tài)內(nèi)部類和匿名內(nèi)部類吠昭。 1、成員內(nèi)部類: 即作為外部類的一個成...
    ikaroskun閱讀 1,223評論 0 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法胧瓜,類相關(guān)的語法矢棚,內(nèi)部類的語法,繼承相關(guān)的語法府喳,異常的語法蒲肋,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • 2014年的蘋果全球開發(fā)者大會(WWDC),當Craig Federighi向全世界宣布“We have new ...
    yeshenlong520閱讀 2,275評論 0 9
  • 心流”:在工作時全神貫注,而忘記時間以及對周圍環(huán)境的感知兜粘,即便沒有報酬也樂在其中强胰。
    思緒的速度閱讀 212評論 0 0
  • 火車轟隆的聲音劃過,帶著希望妹沙,承載思念,車上后排吃著東西的大媽或大姐和一直好奇下一個地點而吵鬧的小男孩熟吏,空氣里的充...
    不問為什么閱讀 161評論 0 1