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

Java instanceof 模式匹配完全指南:從基礎類型判斷到 JDK 16+ 模式匹配增強

     編輯:Java 相關知識

基礎語法與語義

boolean result = obj instanceof Type;
// obj 為 null 時直接返回 false,不拋 NPE
// obj 為 Type 或其子類實例返回 true

核心規則:編譯期類型必須與目標類型有繼承關係(父子、實現、同類),否則編譯錯誤「Incompatible types」。

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

// 傳統寫法:兩次類型檢查
if (obj instanceof String) {
    String s = (String) obj; // 強制轉換
    System.out.println(s.length());
}

// JDK 14+ 模式匹配預覽 / JDK 16+ 正式:一步到位
if (obj instanceof String s) {
    // s 為模式變量,作用域限於 if 塊內
    System.out.println(s.length());
}

// 複雜條件結合
if (obj instanceof List list && !list.isEmpty()) {
    System.out.println("First: " + list.get(0));
}

繼承體系中的行為演示

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

public class InstanceofDemo {
    public static void main(String[] args) {
        Animal a = new Husky();
        
        System.out.println(a instanceof Animal); // true
        System.out.println(a instanceof Dog);    // true
        System.out.println(a instanceof Husky);  // true
        System.out.println(a instanceof Cat);    // false
        System.out.println(a instanceof String); // 編譯錯誤:無關類型
        
        // null 情況
        Animal nullRef = null;
        System.out.println(nullRef instanceof Dog); // false
    }
}

集合元素類型判斷實戰

List mixed = Arrays.asList("hello", 123, new Dog(), 45.6, new Cat());

for (Object obj : mixed) {
    if (obj instanceof String s) {
        System.out.println("String: " + s.toUpperCase());
    } else if (obj instanceof Integer i) {
        System.out.println("Integer: " + (i * 2));
    } else if (obj instanceof Animal a) { // 接口類型匹配
        System.out.println("Animal: " + a.getClass().getSimpleName());
    } else {
        System.out.println("Other: " + obj.getClass());
    }
}
// 輸出:
// String: HELLO
// Integer: 246
// Animal: Dog
// Other: class java.lang.Double
// Animal: Cat

訪問者模式替代方案:密封類 + 模式匹配 (JDK 17+)

// 密封類限制實現類
sealed interface Expr permits Const, Plus, Mult {}
record Const(int value) implements Expr {}
record Plus(Expr left, Expr right) implements Expr {}
record Mult(Expr left, Expr right) implements Expr {}

int eval(Expr expr) {
    return switch (expr) {
        case Const(int v) -> v;
        case Plus(Expr l, Expr r) -> eval(l) + eval(r);
        case Mult(Expr l, Expr r) -> eval(l) * eval(r);
        // 編譯器檢查窮盡性,無需 default
    };
}

優勢:類型安全、編譯期窮盡性檢查、語法簡潔、無需 Visitor 接口樣板代碼。

性能與最佳實踐

  • 性能:JVM 內部優化極快,僅檢查類元數據指針,無額外開銷
  • 避免濫用:大量 instanceof 鏈提示設計缺陷,優先多態、訪問者模式、密封類
  • 泛型擦除限制:obj instanceof List ❌ 編譯錯誤,只能 instanceof List 或 instanceof List
  • 數組類型:obj instanceof int[] ✅,obj instanceof List[] ✅

對比:instanceof vs getClass() == Type.class

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性instanceofgetClass() ==
子類實例truefalse
null 處理false拋 NPE
語義是否為類型族成員是否為精確類型
推薦場景多態類型判斷精確類型校驗(如序列化、複製)