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

Java instanceof 模式匹配完整指南:從基礎用法到 Java 16+ 新特性

     編輯:Java 程式設計入門

基礎語法與語意

boolean result = object instanceof Type;
// 等價於:object != null && object.getClass() 是 Type 或其子類/實現類
  • 返回 boolean,從不拋異常
  • null instanceof Type 永遠返回 false
  • 編譯期類型檢查:若 object 靜態類型與 Type 無繼承關係,直接編譯錯誤

核心規則:繼承鏈向上匹配

interface Animal {}
class Dog implements Animal {}
class Cat implements Animal {}

Animal a = new Dog();
Dog d = new Dog();

a instanceof Animal  // true
a instanceof Dog     // true(運行時類型是 Dog)
a instanceof Cat     // false
d instanceof Animal  // true
d instanceof Dog     // true
d instanceof Cat     // false(編譯期允許,運行時 false)

經典應用場景:類型安全轉型

傳統寫法(Java 16 前)

Object obj = getObject();

if (obj instanceof String) {
    String s = (String) obj;  // 需顯式強轉
    System.out.println(s.toUpperCase());
} else if (obj instanceof Integer) {
    Integer i = (Integer) obj;
    System.out.println(i * 2);
}

Java 16+ 模式匹配 instanceof(JEP 394)

Object obj = getObject();

if (obj instanceof String s) {      // 直接宣告模式變數
    System.out.println(s.toUpperCase());  // s 僅在 true 分支作用域有效
} else if (obj instanceof Integer i) {
    System.out.println(i * 2);
}

// 作用域規則:模式變數僅在 instanceof 為 true 時確定賦值
// 以下編譯錯誤:
// if (obj instanceof String s) { } 
// s.toUpperCase();  // s 不在作用域

進階模式:密封類與 switch 表達式(Java 17+)

sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
record Triangle(double a, double b, double c) implements Shape {}

public double area(Shape shape) {
    return switch (shape) {
        case Circle c -> Math.PI * c.radius() * c.radius();
        case Rectangle r -> r.w() * r.h();
        case Triangle t -> {
            double s = (t.a() + t.b() + t.c()) / 2;
            yield Math.sqrt(s * (s - t.a()) * (s - t.b()) * (s - t.c()));
        }
        // 密封類保證窮盡,無需 default
    };
}

實戰範例:集合中異構對象處理

List items = List.of("hello", 123, 45.6, true, List.of(1,2));

for (Object item : items) {
    if (item instanceof String s) {
        System.out.println("字串: " + s.length());
    } else if (item instanceof Integer i) {
        System.out.println("整數: " + i * 2);
    } else if (item instanceof Double d) {
        System.out.println("浮點: " + String.format("%.2f", d));
    } else if (item instanceof Boolean b) {
        System.out.println("布林: " + b);
    } else if (item instanceof List list) {
        System.out.println("列表大小: " + list.size());
    } else {
        System.out.println("其他: " + item.getClass().getSimpleName());
    }
}

效能考量

  • instanceof 極快(JVM 內建指令),納秒級
  • 避免在極熱路徑(百萬級/秒)大量使用,考慮多態設計替代
  • 模式匹配版無額外開銷,編譯器生成等效字節碼

常見誤區與避坑

誤區正確認知
instanceof 檢查具體類而非介面可檢查類、介面、陣列類型、record、enum
null 會拋 NPEnull instanceof X 直接返回 false,安全
模式變數可在外部使用作用域僅限於 true 分支(flow scoping)
可用於基本型別僅限引用類型,int/boolean 等不可用
泛型類型可完整檢查運行時類型擦除,List instanceof List 編譯錯誤,只能 instanceof List

最佳實踐總結

  1. 優先多態:能用方法覆寫解決的,不用 instanceof
  2. 次選模式匹配:Java 16+ 環境必用 instanceof Type var
  3. 密封類 + switch:領域建模首選,編譯器保證窮盡性
  4. 邊界處理:null 安全、泛型擦除限制、基本型別不可用
  5. 測試覆蓋:確保所有分支(含 false 路徑)有測試

總結

instanceof 從簡單的類型檢查進化為強大的模式匹配工具。配合 sealed、record、switch 表達式,Java 實現了接近函數式語言的代數資料類型解構能力。現代 Java 開發者應熟練掌握 instanceof Type var 語法,並在領域建模中善用密封類層次結構,讓編譯器幫你檢查邏輯完整性。

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