objectReference instanceof TypeName
boolean。null,結果為 false)。String s = "Hello";
boolean b1 = s instanceof Object; // true (String 繼承 Object)
boolean b2 = s instanceof CharSequence; // true (String 實作 CharSequence)
boolean b3 = s instanceof StringBuilder; // false
boolean b4 = null instanceof String; // false (null 無型別)
public double calculate(Bill bill) {
if (bill instanceof PhoneBill) {
return calculatePhone((PhoneBill) bill);
}
if (bill instanceof GasBill) {
return calculateGas((GasBill) bill);
}
throw new IllegalArgumentException("Unknown bill type");
}
public double calculate(PhoneBill bill) { ... }
public double calculate(GasBill bill) { ... }
// 呼叫端:calculate(bill) 自動依靜態型別分派
缺點:靜態綁定,若參考型別為 Bill 則無法動態分派。
public abstract class Bill {
public abstract double calculate();
}
public class PhoneBill extends Bill {
@Override public double calculate() { ... }
}
public class GasBill extends Bill {
@Override public double calculate() { ... }
}
// 使用端
double amount = bill.calculate(); // 動態分派,零 instanceof
適用於「演算法穩定、資料結構易變」場景:
interface BillVisitor {
void visit(PhoneBill b);
void visit(GasBill b);
}
interface Bill {
void accept(BillVisitor v);
}
class PhoneBill implements Bill {
public void accept(BillVisitor v) { v.visit(this); }
}
if (!(obj instanceof MyClass)) return false;if (obj instanceof String s) { // 直接宣告並轉型
System.out.println(s.toUpperCase());
}
// 等同於
if (obj instanceof String) {
String s = (String) obj;
...
}
instanceof 是工具,非原罪。業務邏輯中大量使用 instanceof 通常意味著領域模型缺乏多型設計。優先採用「覆寫多型方法」或「Visitor 模式」,僅在邊界層(equals、序列化、框架整合)合理使用。Java 16+ 模式匹配語法讓合法用例更簡潔安全。