Java
通過對Java語言規范進行修改
顯著簡化了一些實用結構的實現
在那些修改中
最引人注目的就是內部類和匿名類
如運用得當
它們可使程序更易理解和維護
本文介紹內部類和匿名類在Java代碼中是如何具體工作的
如何正確使用它們
以及如何避免一些常見的錯誤
下面來看看這些特性具體是如何工作的?
非靜態內部類
如果內部類沒有指定static修飾符
就擁有對外部類的所有成員的完全訪問權限
包括實例字段和方法
為實現這一行為
非靜態內部類存儲著對外部類的實例的一個隱式引用
所以
對一個非靜態內部類進行實例化需要采用不同語法的new語句
引用內部類
內部類最自然的一種應用就是聲明只在另一個類的內部使用的類
或者聲明與另一個類密切相關的類
如清單B所示
它是一個鏈表的簡單實現
由於Node類通常只在LinkedList的范圍內使用
所以最好將Node聲明為LinkedList的一個內部類
適用於類成員的訪問控制修改符也適用於內部類
也就是說
內部類可以具有package
protected
private和public訪問權限
它們的語義和正常的語義沒有什麼不同
由於Node要在LinkedList的外部使用
所以把它聲明為public
然而
修飾符static具有不同的含義
應用於內部類時
它聲明的類具有與其他類相同的語義
也就是可進行實例化
並像一個標准類那樣使用
惟一的區別就是它擁有對外部類的所有靜態成員的完全訪問權限
清單C展示了一個簡單的程序
它創建一個鏈表
並將它打印到標准輸出設備
更優化的代碼
內部和匿名類是Java
為我們提供的兩個出色的工具
它們提供了更好的封裝
結果就是使代碼更容易理解和維護
使相關的類都能存在於同一個源代碼文件中(這要歸功於內部類)
並能避免一個程序產生大量非常小的類(這要歸功於匿名類)
new
這種形式的new語句要求外部類的一個實例
使內部類能在那個實例的上下文中創建
注意清單A聲明了幾個非靜態內部類
並用標准的new語句在Method
中實例化它們
之所以能那樣做
是因為Method
是外部類的一個實例方法
所以new語句會在外部類的一個實例的上下文中隱式地執行
只有在外部類的外部或者在其他對象的上下文中實例化一個非靜態內部類時
才需要使用修改過的語法
但是
非靜態內部類具有一些限制
尤其是
它們不能聲明靜態初始化列表和靜態成員
除非是在常量字段中
此外
方法內部聲明的內部類不能訪問方法的局部變量和參數
除非它們被初始化成final
匿名類
匿名類是不能有名稱的類
所以沒辦法引用它們
必須在創建時
作為new語句的一部分來聲明它們
這就要采用另一種形式的new語句
如下所示
new <類或接口> <類的主體>
這種形式的new語句聲明一個新的匿名類
它對一個給定的類進行擴展
或者實現一個給定的接口
它還創建那個類的一個新實例
並把它作為語句的結果而返回
要擴展的類和要實現的接口是new語句的操作數
後跟匿名類的主體
如果匿名類對另一個類進行擴展
它的主體可以訪問類的成員
覆蓋它的方法等等
這和其他任何標准的類都是一樣的
如果匿名類實現了一個接口
它的主體必須實現接口的方法
注意匿名類的聲明是在編譯時進行的
實例化在運行時進行
這意味著for循環中的一個new語句會創建相同匿名類的幾個實例
而不是創建幾個不同匿名類的一個實例
從技術上說
匿名類可被視為非靜態的內部類
所以它們具有和方法內部聲明的非靜態內部類一樣的權限和限制
如果要執行的任務需要一個對象
但卻不值得創建全新的對象(原因可能是所需的類過於簡單
或者是由於它只在一個方法內部使用)
匿名類就顯得非常有用
匿名類尤其適合在Swing應用程序中快速創建事件處理程序
清單D就是一個非常簡單的Swing應用程序
它展示了與匿名類有關的幾個概念
這個例子創建了兩個匿名類
第一個對java
awt
event
WindowAdapter進行擴展
並在應用程序窗口關閉時調用應用程序的onClose方法
即使onClose聲明為private
匿名類也能調用它
因為匿名類本質上是應用程序類的一個內部類
第二個匿名類實現了java
awt
ActionListener接口
它在一個按鈕被按下後關閉應用程序窗口
注意匿名類可以訪問本地變量frame
這是由於匿名類在與frame相同的方法內部聲明
然而
frame要被聲明為final
否則會生成編譯錯誤
內部類
簡單地說
內部類
是在另一個類的內部聲明的類
從Java
開始
你可在一個類中聲明另一個類
這與聲明字段和方法非常相似
包裝了內部類聲明的類就稱為
外部類
實際上
Java語言規范還允許你做更多的事情
包括
在另一個類或者一個接口中聲明一個類
在另一個接口或者一個類中聲明一個接口
在一個方法中聲明一個類
類和接口聲明可嵌套任意深度
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26979.html