Java內(nèi)部類有什么用?及各類內(nèi)部類解析

java內(nèi)部類有什么用?

搬運(yùn)一下oracle文檔:

https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

總結(jié)起來就是三點(diǎn):

1. 有些類只對另外一個類有用, 這樣可以組合在一起,讓整個包更精簡。比如Builder常常作為靜態(tài)內(nèi)部類。

2. 增加封裝性。 比如有兩個類A和B,B想要access A的成員。 如果將B作為A的內(nèi)部類,A的成員可以保持private,并且B本身也被封裝起來了。

3. 增加可讀性和維護(hù)性。讓代碼離它被用到的地方更近了。

內(nèi)部類(inner class)

  1. 擁有外部類的引用,這樣內(nèi)部類可以訪問創(chuàng)建它的外部類的內(nèi)容,甚至包括私有變量。
  2. 一旦編譯成功,就會成為完全不同的兩類。
    對于一個名為outer的外部類和inner的內(nèi)部類,編譯完之后出現(xiàn)outer.class和outer$inner.class兩類。
  3. 如果在外部類外部訪問內(nèi)部類,用out.inner
    在外部類外部要生成一個內(nèi)部類對象:Outer.Inner in = Outer.new.Inner()
  4. 外部類可以訪問內(nèi)部類的private成員,神奇不神奇。
    編譯器實(shí)現(xiàn)的時候是這樣的:Outer類和Inner類不再是嵌套結(jié)構(gòu),而是變?yōu)橐粋€包中的兩個類,然后,對于private變量的訪問,編譯器會生成一個accessor函數(shù).......
  5. 非靜態(tài)內(nèi)部類不能有靜態(tài)數(shù)據(jù)、靜態(tài)方法、靜態(tài)內(nèi)部類。
    為啥呢?因?yàn)?,非靜態(tài)內(nèi)部類的訪問必須通過外部類的實(shí)例,所以要訪問非靜態(tài)內(nèi)部類的靜態(tài)方法,必須先實(shí)例化內(nèi)部類和外部類,這樣就和靜態(tài)成員的設(shè)計(jì)是違背的。

靜態(tài)內(nèi)部類(靜態(tài)嵌套類)(nested class)

  1. 實(shí)際上是一種外部類,因?yàn)榕c外部類的實(shí)例無關(guān)
  2. 定義在類中,方法外
  3. 只能訪問外部類的靜態(tài)成員(可以訪問私有的靜態(tài)成員)
  4. new的時候不需要外部類成員:Outer.Inner in = new Outer.Inner();

局部內(nèi)部類

  1. 在一個方法甚至一個代碼塊之內(nèi)。

  2. 可以被final或abstract修飾

  3. 不能含有靜態(tài)成員

  4. 局部內(nèi)部類訪問外部類方法的局部變量要求其必須為final。
    局部變量是隨著方法的調(diào)用而調(diào)用,隨著調(diào)用完畢而消失。而堆內(nèi)存的對象內(nèi)容并不會立即消失。
    或者簡單的來說是作用域的問題。就好像方法外面做的事情并不能改變方法內(nèi)才定義的變量,因?yàn)槟悴⒉恢婪椒ɡ锩孢@個時候已經(jīng)存在了這個局部變量了沒有。在這個內(nèi)部類中方法里面的本地變量是失效的,也就是不在作用域內(nèi),所以是不能夠訪問的。但是為什么這里用final卻又可以訪問呢? 因?yàn)镴ava采用了一種copy local variable的方式來實(shí)現(xiàn),也就是說把定義為final的局部變量拷貝過來用,而引用的也可以拿過來用,只是不能重新賦值。從而造成了可以access local variable的假象,而這個時候由于不能重新賦值,所以一般不會造成不可預(yù)料的事情發(fā)生。
    則java編譯器則會在內(nèi)部類NewAge內(nèi)生成一個外部變量的拷貝,而且可以既可以保證內(nèi)部類可以引用外部屬性,又能保證值的唯一性
    也就是拷貝了一個變量的副本,提供給局部內(nèi)部類,這個副本的生命周期和局部內(nèi)部類一樣長,并且這個副本不可以修改,保證了數(shù)據(jù)的同步
    注意:在Java8 中,被局部內(nèi)部類引用的局部變量,默認(rèn)添加final,所以不需要添加final關(guān)鍵詞

匿名內(nèi)部類

  1. 匿名類(Anonymouse Class)是一種沒有類名的內(nèi)部類,多用在事件處理的程序中。有時用戶需要定義一個類,且只想在程序中定義該類的一個對象,并把它作為參數(shù)傳遞給一個方法。只要該類是一個現(xiàn)有類的派生或?qū)崿F(xiàn)一個接口,就可以使用匿名類。匿名類定義短而簡單且使用方便,但不易過多使用,它會引起程序代碼的復(fù)雜化而不易理解
  2. 沒有名字,所以不能定義構(gòu)造方法。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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