首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

【Java 每日一題】20161125:匿名內部類與雙大括號初始化的 Class 對象比較

     編輯:Java 綜合教學

題目代碼

package Nov2016;
import java.util.LinkedList;
import java.util.List;

public class Ques1125 {
    public static void main(String[] args){
        List list01 = new LinkedList();
        List list02 = new LinkedList(){};
        List list03 = new LinkedList(){{}};

        System.out.println(list01.getClass() == list02.getClass());
        System.out.println(list02.getClass() == list03.getClass());
        System.out.println(list01.getClass() == list03.getClass());
    }
}

核心知識點

寫法語法本質編譯產物getClass() 結果
new LinkedList()普通實例化LinkedList.classclass java.util.LinkedList
new LinkedList(){}匿名內部類,**無實例初始化塊**Ques1125$1.classclass Nov2016.Ques1125$1
new LinkedList(){{}}匿名內部類,**含空實例初始化塊**Ques1125$2.classclass Nov2016.Ques1125$2

輸出結果

false
false
false

詳細解析

  1. list01 是 LinkedList 直接實例,getClass() == LinkedList.class → true(但這裡比較的是引用相等性)。
  2. list02、list03 分別是兩個不同的匿名內部類,編譯器生成 Ques1125$1 和 Ques1125$2 兩個獨立 .class 文件。
  3. 每個匿名內部類都是獨立類型,即使父類相同、主體為空,**getClass() 返回不同的 Class 對象**
  4. 因此三組 == 比較全部為 false。

延伸:雙大括號初始化的代價

// 這樣寫會產生什麼?
Map map = new HashMap<>() {{
    put("k1", "v1");
    put("k2", "v2");
}};
  • 產生匿名內部類 YourClass$1,持有外部類引用(可能導致記憶體洩漏)。
  • 序列化時需外部類也實現 Serializable。
  • 現代替代方案:Java 9+ Map.of("k1","v1","k2","v2")、Guava ImmutableMap.of()、或靜態工廠方法。

總結

匿名內部類每次聲明即生成新類型,getClass() 必不相等。面試考察點:
1. 語法糖本質(編譯器生成 Outer$N.class)
2. 雙大括號初始化的副作用(內存洩漏、序列化麻煩、類爆炸)
3. == 比較 Class 對象時比較的是同一個 ClassLoader 加載的同一個類。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved