《Java編程的邏輯》筆記21--內(nèi)部類(lèi)的本質(zhì)

內(nèi)部類(lèi)的本質(zhì).png

什么是內(nèi)部類(lèi)

個(gè)類(lèi)放在另一個(gè)類(lèi)的內(nèi)部,稱(chēng)之為內(nèi)部類(lèi)

為什么要放到別的類(lèi)內(nèi)部呢溜哮?

內(nèi)部類(lèi)與包含它的外部類(lèi)有比較密切的關(guān)系悠栓,而與其他類(lèi)關(guān)系不大,定義在類(lèi)內(nèi)部惫周,可以實(shí)現(xiàn)對(duì)外部完全隱藏尘惧,可以有更好的封裝性,代碼實(shí)現(xiàn)上也往往更為簡(jiǎn)潔递递。

注意點(diǎn)

對(duì)于Java虛擬機(jī)而言喷橙,它是不知道內(nèi)部類(lèi)這回事的, 每個(gè)內(nèi)部類(lèi)最后都會(huì)被編譯為一個(gè)獨(dú)立的類(lèi)啥么,生成一個(gè)獨(dú)立的字節(jié)碼文件

根據(jù)定義的位置和方式不同,分四種

靜態(tài)內(nèi)部類(lèi)

  • 語(yǔ)法
    靜態(tài)內(nèi)部類(lèi)與靜態(tài)變量和靜態(tài)方法定義的位置一樣贰逾,也帶有static關(guān)鍵字悬荣,只是它定義的是類(lèi)


    image.png

可以訪問(wèn)外部類(lèi)的靜態(tài)變量和方法, 不可以訪問(wèn)實(shí)例變量和方法疙剑。 在類(lèi)內(nèi)部氯迂,可以直接使用內(nèi)部靜態(tài)類(lèi)
public靜態(tài)內(nèi)部類(lèi)可以被外部使用, 需要通過(guò)"外部類(lèi).靜態(tài)內(nèi)部類(lèi)"的方式使用

  • 實(shí)現(xiàn)原理
    以上代碼實(shí)際上會(huì)生成兩個(gè)類(lèi)核芽,一個(gè)是Outer囚戚,另一個(gè)是Outer$StaticInner
    image.png

內(nèi)部類(lèi)訪問(wèn)了外部類(lèi)的一個(gè)私有靜態(tài)變量shared酵熙, 而我們知道私有變量是不能被類(lèi)外部訪問(wèn)的轧简, Java的解決方法是,自動(dòng)為Outer生成了一個(gè)非私有訪問(wèn)方法access$0匾二, 它返回這個(gè)私有靜態(tài)變量shared哮独。

  • 使用場(chǎng)景
    如果它與外部類(lèi)關(guān)系密切,且不依賴(lài)于外部類(lèi)實(shí)例察藐,則可以考慮定義為靜態(tài)內(nèi)部類(lèi)
    LinkedList類(lèi)內(nèi)部有一個(gè)私有靜態(tài)內(nèi)部類(lèi)Node

成員內(nèi)部類(lèi)

  • 語(yǔ)法
    成員內(nèi)部類(lèi)沒(méi)有static修飾符
    image.png

與靜態(tài)內(nèi)部類(lèi)不同皮璧,除了靜態(tài)變量和方法, 成員內(nèi)部類(lèi)還可以直接訪問(wèn)外部類(lèi)的實(shí)例變量和方法
在外部類(lèi)內(nèi)分飞,使用成員內(nèi)部類(lèi)與靜態(tài)內(nèi)部類(lèi)是一樣的悴务, 直接使用即可,如test()方法所示譬猫。與靜態(tài)內(nèi)部類(lèi)不同讯檐, 成員內(nèi)部類(lèi)對(duì)象總是與一個(gè)外部類(lèi)對(duì)象相連的, 在外部使用時(shí)染服,它不能直接通過(guò)new Outer.Inner()的方式創(chuàng)建對(duì)象别洪, 而是要先將創(chuàng)建一個(gè)Outer類(lèi)對(duì)象


image.png

與靜態(tài)內(nèi)部類(lèi)不同,成員內(nèi)部類(lèi)中不可以定義靜態(tài)變量和方法 (final變量例外柳刮,它等同于常量)挖垛, 下面介紹的方法內(nèi)部類(lèi)和匿名內(nèi)部類(lèi)也都不可以

  • 實(shí)現(xiàn)原理
    以上代碼也會(huì)生成兩個(gè)類(lèi),一個(gè)是Outer秉颗,另一個(gè)是Outer$Inner
    image.png

    image.png

Outer$Inner類(lèi)有個(gè)實(shí)例變量outer指向外部類(lèi)的對(duì)象痢毒, 它在構(gòu)造方法中被初始化,Outer在新建Outer$Inner對(duì)象時(shí)傳遞當(dāng)前對(duì)象給它蚕甥, 由于內(nèi)部類(lèi)訪問(wèn)了外部類(lèi)的私有變量和方法哪替, 外部類(lèi)Outer生成了兩個(gè)非私有靜態(tài)方法,access$0用于訪問(wèn)變量a梢灭,access$1用于訪問(wèn)方法action夷家。

  • 使用場(chǎng)景
    如果內(nèi)部類(lèi)與外部類(lèi)關(guān)系密切蒸其,且操作或依賴(lài)外部類(lèi)實(shí)例變量和方法,則可以考慮定義為成員內(nèi)部類(lèi)库快。
    外部類(lèi)的一些方法的返回值可能是某個(gè)接口摸袁,為了返回這個(gè)接口,外部類(lèi)方法可能使用內(nèi)部類(lèi)實(shí)現(xiàn)這個(gè)接口义屏,這個(gè)內(nèi)部類(lèi)可以被設(shè)為private靠汁,對(duì)外完全隱藏。
    LinkedList中闽铐,它的兩個(gè)方法listIterator和descendingIterator的返回值都是接口Iterator蝶怔, 調(diào)用者可以通過(guò)Iterator接口對(duì)鏈表遍歷,listIterator和descendingIterator內(nèi)部分別使用了成員內(nèi)部類(lèi)ListItr和DescendingIterator兄墅,這兩個(gè)內(nèi)部類(lèi)都實(shí)現(xiàn)了接口Iterator

方法內(nèi)部類(lèi)

  • 語(yǔ)法
    內(nèi)部類(lèi)還可以定義在一個(gè)方法體中


    image.png

類(lèi)Inner定義在外部類(lèi)方法test中踢星,方法內(nèi)部類(lèi)只能在定義的方法內(nèi)被使用。 如果方法是實(shí)例方法隙咸,則除了靜態(tài)變量和方法沐悦,內(nèi)部類(lèi)還可以直接訪問(wèn)外部類(lèi)的實(shí)例變量和方法,如innerMethod直接訪問(wèn)了外部私有實(shí)例變量a五督。如果方法是靜態(tài)方法藏否,則方法內(nèi)部類(lèi)只能訪問(wèn)外部類(lèi)的靜態(tài)變量和方法。
方法內(nèi)部類(lèi)還可以直接訪問(wèn)方法的參數(shù)和方法中的局部變量充包,不過(guò)副签, 這些變量必須被聲明為final,如innerMethod直接訪問(wèn)了方法參數(shù)param和局部變量str基矮。

  • 實(shí)現(xiàn)原理

    image.png

    image.png

方法內(nèi)部類(lèi)可以訪問(wèn)方法中的參數(shù)和局部變量淆储,這是通過(guò)在構(gòu)造方法中傳遞參數(shù)來(lái)實(shí)現(xiàn)的
方法內(nèi)部類(lèi)操作的并不是外部的變量,而是它自己的實(shí)例變量愈捅,只是這些變量的值和外部一樣遏考, 對(duì)這些變量賦值,并不會(huì)改變外部的值蓝谨,為避免混淆灌具,所以干脆強(qiáng)制規(guī)定必須聲明為final。
如果的確需要修改外部的變量譬巫,可以將變量改為只含該變量的數(shù)組

image.png

  • 使用場(chǎng)景
    方法內(nèi)部類(lèi)都可以用成員內(nèi)部類(lèi)代替咖楣,至于方法參數(shù),也可以作為參數(shù)傳遞給成員內(nèi)部類(lèi)芦昔。 不過(guò)诱贿,如果類(lèi)只在某個(gè)方法內(nèi)被使用,使用方法內(nèi)部類(lèi),可以實(shí)現(xiàn)更好的封裝珠十。

匿名內(nèi)部類(lèi)

  • 語(yǔ)法
    匿名內(nèi)部類(lèi)沒(méi)有名字料扰,在創(chuàng)建對(duì)象的同時(shí)定義類(lèi)


    image.png
    image.png

匿名內(nèi)部類(lèi)只能被使用一次,用來(lái)創(chuàng)建一個(gè)對(duì)象焙蹭。它沒(méi)有名字晒杈,沒(méi)有構(gòu)造方法
因?yàn)闆](méi)有構(gòu)造方法,它自己無(wú)法接受參數(shù)孔厉,如果必須要參數(shù)拯钻,則應(yīng)該使用其他內(nèi)部類(lèi)。
與方法內(nèi)部類(lèi)一樣撰豺,匿名內(nèi)部類(lèi)也可以訪問(wèn)外部類(lèi)的所有變量和方法粪般,可以訪問(wèn)方法中的final參數(shù)和局部變量。

  • 實(shí)現(xiàn)原理
    每個(gè)匿名內(nèi)部類(lèi)也都被生成為了一個(gè)獨(dú)立的類(lèi)污桦,只是類(lèi)的名字以外部類(lèi)加數(shù)字編號(hào)亩歹,沒(méi)有有意義的名字。


    image.png

    image.png

與方法內(nèi)部類(lèi)類(lèi)似寡润,外部實(shí)例this捆憎,方法參數(shù)x和y都作為參數(shù)傳遞給了內(nèi)部類(lèi)構(gòu)造方法舅柜。 此外梭纹,new時(shí)的參數(shù)2和3也傳遞給了構(gòu)造方法,內(nèi)部類(lèi)構(gòu)造方法又將它們傳遞給了父類(lèi)構(gòu)造方法致份。

  • 使用場(chǎng)景
    匿名內(nèi)部類(lèi)能做的变抽,方法內(nèi)部類(lèi)都能做。但如果對(duì)象只會(huì)創(chuàng)建一次氮块,且不需要構(gòu)造方法來(lái)接受參數(shù)绍载,則可以使用匿名內(nèi)部類(lèi),代碼書(shū)寫(xiě)上更為簡(jiǎn)潔滔蝉。
    匿名內(nèi)部類(lèi)還經(jīng)常用于事件處理程序中击儡,用于響應(yīng)某個(gè)事件,比如說(shuō)一個(gè)Button蝠引,處理點(diǎn)擊事件的代碼可能類(lèi)似如下:


    image.png

將程序分為保持不變的主體框架阳谍,和針對(duì)具體情況的可變邏輯, 通過(guò)回調(diào)的方式進(jìn)行協(xié)作螃概,是計(jì)算機(jī)程序的一種常用實(shí)踐矫夯。匿名內(nèi)部類(lèi)是實(shí)現(xiàn)回調(diào)接口的一種簡(jiǎn)便方式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吊洼,一起剝皮案震驚了整個(gè)濱河市训貌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖递沪,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豺鼻,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡款慨,警方通過(guò)查閱死者的電腦和手機(jī)拘领,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)樱调,“玉大人约素,你說(shuō)我怎么就攤上這事“柿瑁” “怎么了圣猎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)乞而。 經(jīng)常有香客問(wèn)我送悔,道長(zhǎng),這世上最難降的妖魔是什么爪模? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任欠啤,我火速辦了婚禮,結(jié)果婚禮上屋灌,老公的妹妹穿的比我還像新娘洁段。我一直安慰自己,他們只是感情好共郭,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布祠丝。 她就那樣靜靜地躺著,像睡著了一般除嘹。 火紅的嫁衣襯著肌膚如雪写半。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,736評(píng)論 1 312
  • 那天尉咕,我揣著相機(jī)與錄音叠蝇,去河邊找鬼。 笑死年缎,一個(gè)胖子當(dāng)著我的面吹牛悔捶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晦款,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼炎功,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了缓溅?” 一聲冷哼從身側(cè)響起蛇损,我...
    開(kāi)封第一講書(shū)人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后淤齐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體股囊,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年更啄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稚疹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡祭务,死狀恐怖内狗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情义锥,我是刑警寧澤柳沙,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站拌倍,受9級(jí)特大地震影響赂鲤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柱恤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一数初、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梗顺,春花似錦泡孩、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至矗漾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間薄料,已是汗流浹背敞贡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摄职,地道東北人誊役。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像谷市,于是被迫代替她去往敵國(guó)和親蛔垢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

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

  • Java 內(nèi)部類(lèi) 分四種:成員內(nèi)部類(lèi)迫悠、局部?jī)?nèi)部類(lèi)鹏漆、靜態(tài)內(nèi)部類(lèi)和匿名內(nèi)部類(lèi)。 1、成員內(nèi)部類(lèi): 即作為外部類(lèi)的一個(gè)成...
    ikaroskun閱讀 1,239評(píng)論 0 13
  • 可以將一個(gè)類(lèi)定義在另一個(gè)類(lèi)或方法中艺玲,這樣的類(lèi)叫做內(nèi)部類(lèi) --《Thinking in Java》 說(shuō)起內(nèi)部類(lèi)括蝠,...
    dengchengchao_閱讀 434評(píng)論 0 2
  • 注意注意!7咕邸忌警!前排提示!C胧帷法绵!本篇文章過(guò)長(zhǎng),最好收藏下來(lái)慢慢看酪碘,如果你之前對(duì)內(nèi)部類(lèi)不是很熟悉礼烈,一次性看完,大概你會(huì)懵...
    Sharember閱讀 851評(píng)論 0 10
  • 小胖從官網(wǎng)出發(fā)婆跑,研究下為什么我們需要些內(nèi)部類(lèi)此熬,內(nèi)部類(lèi)的區(qū)別和聯(lián)系。思考三個(gè)問(wèn)題:(1)為什么需要內(nèi)部類(lèi)滑进?靜態(tài)內(nèi)部類(lèi)...
    小胖學(xué)編程閱讀 1,690評(píng)論 0 6
  • 面向?qū)ο笾饕槍?duì)面向過(guò)程犀忱。 面向過(guò)程的基本單元是函數(shù)。 什么是對(duì)象:EVERYTHING IS OBJECT(萬(wàn)物...
    sinpi閱讀 1,059評(píng)論 0 4