匿名內部類精講
匿名內部類別適合建立那種只需要一次使用的類,例如命令模式時所需要的Command物件。匿名內部類別的語法有點奇怪,在創建匿名內部類別時會立即創建一個該類別的實例,這個類別定義立即消失,匿名內部類別不能重複使用。
定義匿名內部類別的格式如下:
new 父类构造器(参数列表)|实现接口() { //匿名内部类的类体部分 }
從上面定義可以看出,匿名內部類別必須繼承一個父類,或實作一個接口,但最多只能繼承一個父類,或實作一個介面。
關於匿名內部類別還有以下兩條規則:
1)匿名內部類別不能是抽象類別,因為系統在建立匿名內部類別的時候,會立即建立內部類別的物件。因此不允許將匿名內部類別
定義成抽象類別。
2)匿名內部類別不等定義建構器,因為匿名內部類別沒有類別名,所以無法定義建構器,但匿名內部類別可以定義實例初始化區塊,
透過實例初始化區塊來完成建構器需要完成的事情。
最常用的建立匿名內部類別的方式是需要建立某個介面類型的對象,如下程式所示:
interface Product{ public double getPrice(); public String getName(); } public class TestAnonymous{ public void test(Product p){ System.out.println("购买了一个"+p.getName()+",花掉 了"+p.getPrice()); } public static void main(String[]args){ TestAnonymous ta = new TestAnonymous(); ta.test(new Product(){ public double getPrice(){ return 567; } public String getName(){ return "AGP显卡"; } }); } }
上面程式中的TestAnonymous類別定義了一個test方法,該方法需要一個Product物件作為參數,但Product只是一個接口,
無法直接創建對象,因此此處考慮創建一個Product接口實現類的對象傳入該方法---如果這個Product接口實現類需要重複
使用,則應該經該實現類定義一個獨立類別;如果這個Product介面實作類別只需一次使用,則可採用上面程式中的方式,定義
一個匿名內部類別。
如同上述程式中看到,定義匿名類別不需要class關鍵字,而是在定義匿名內部類別時直接產生該匿名內部類別的物件。上面
粗體字碼部分就是匿名類別的類體部分。
由於匿名內部類別不能是抽象類別,所以匿名內部類別必須實作它的抽象父類別或介面裡包含的所有抽象方法。
對於上面建立Product實作類別物件的程式碼,可以拆分成以下程式碼:
class AnonymousProduct implements Product{ public double getPrice(){ return 567; } public String getName(){ return "AGP显卡"; } } ta.test(new AnonymousProduct());
當透過實作介面來建立匿名內部類別時,匿名內部類別也不能顯示建立建構器,因此匿名內部類別只有一個隱式的無參數建構
器,故new介面名後的括號裡不能傳入參數值。
但如果透過繼承父類別來建立匿名內部類別是,匿名內部類別將擁有和父類別相似的建構器,此處的相似指的是擁有相同的形參
列表。
abstract class Device{ private String name; public Device(){ } public Device(String name){ this.name = name; } public abstract double getPrice(); //此处省略了name属性的setter和getter方法 } public class AnonymousInner{ public void test(Device d){ System.out.println("购买了一个"+d.getName()+",花掉了"+d.getPrice()); } public static void main(String[] args){ AnonymousInner ai = new AnonymousInner(); //调用有参数的构造器创建Device匿名实现类的对象 ai.test(new Device("电子示波器"){ public double getPrice(){ return 67; } }); //调用无参数的构造器创建Device匿名实现类的对象 Device d = new Device(){ //初始化块 { System.out.println("匿名内部类的初始化块..."); } //实现抽象方法 public double getPrice(){ return 56; } public Sting getName(){ return "键盘"; } }; ai.test(d); } }
上面程式建立了一個抽象父類別Device,這個抽象父類別裡包含兩個建構器:一個無參數的,一個有參數的。當建立以Device
為父類別的匿名內部類別時,即可以傳入參數(如上方程式中第一段粗體字部分),也可以不傳入參數(如上方程式中第二段粗體
字部分)。
當建立匿名內部類別時,必須實作介面或抽象父類別裡的所有抽象方法。如果有需要,也可以重寫父類別中的普通方法,如上面
程式的第二段粗體字程式碼部分,匿名內部類別重寫了抽象父類別Device類別的getName方法,其中getName方法並不是抽象方法。
如果匿名內部類別需要存取外部類別的局部變量,則必須使用final修飾符來修飾外部類別的局部變量,
否則系統將會錯誤。
interface A{ void test(); } public class TestA{ public static void main(Strign[] args){ int age = 0; A a = new A(){ public void test(){ //下面语句将提示错误:匿名内部类内访问局部变量必须使用final修饰 System.out.println(age); } }; } }
上面程式中粗體子程式碼是匿名內部類別存取了外部類別的局部變量,由於age變數沒有使用final修飾符修飾,所以粗體字程式碼將
引起編譯異常。
更多匿名內部類精講相關文章請關注PHP中文網!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

匿名內部類別可導致記憶體洩漏,問題在於它們持有外部類別的引用,從而阻止外部類別被垃圾回收。解決方法包括:1.使用弱引用,當外部類別不再被強引用持有時,垃圾回收器會立即回收弱引用物件;2.使用軟引用,垃圾回收器會在進行垃圾回收時需要記憶體時才回收軟引用物件。在實戰中,例如Android應用程式中,可以透過使用弱引用來解決因匿名內部類別引起的記憶體洩漏問題,從而在不需要監聽器時回收匿名內部類別。

匿名內部類別是Java中沒有明確名稱、透過new表達式創建的特殊內部類,主要用於實作特定介面或擴展抽象類,並在創建後立即使用。常見的匿名內部類別設計模式包括:適配器模式:將一個介面轉換為另一個介面。策略模式:定義和替換演算法。觀察者模式:註冊觀察者並處理事件。它在實際應用中非常有用,例如按字串長度排序TreeSet、建立匿名執行緒等。

匿名內部類別在Java中作為方便建立子類別、簡化程式碼和處理事件(例如按鈕點擊)的特殊內部類別。實戰案例包括:事件處理:使用匿名內部類別為按鈕新增點選事件監聽器。資料轉換:使用Collections.sort方法和匿名內部類別作為比較器對集合進行排序。

匿名內部類別的限制包括:無法存取外部局部變數;無法直接存取外部this引用;無法拋出checked異常;程式碼冗餘;無法序列化。

匿名內部類別的效能問題在於每次使用都會重新創建,可透過以下策略最佳化:1.將匿名內部類別儲存在局部變數中;2.使用非靜態內部類別;3.使用lambda表達式。實戰測試顯示lambda表達式最佳化效果最佳。

匿名內部類別可簡化多執行緒程式碼的創建,無需命名,支援即時定義和使用執行緒類別。主要優勢在於簡化程式碼,而限制是無法擴展。在需要快速建立一兩個執行緒時使用,保持程式碼簡短,如果需要更複雜的邏輯,應建立單獨的類別檔案。
