0Pricing
Java Academy · บทเรียน

ตัวดำเนินการ instanceof

ใช้ instanceof ตรวจสอบชนิดของออบเจ็กต์ก่อนแคสต์ และหลีกเลี่ยง ClassCastException

ตัวดำเนินการ instanceof เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

ตัวดำเนินการ instanceof

ตัวดำเนินการ instanceof ตรวจสอบขณะทำงานว่าวัตถุเป็นอินสแตนซ์ของชนิดที่กำหนดหรือไม่ โดยคืนค่าเป็น true หรือ false และป้องกัน ClassCastException ก่อนการแคสต์

การใช้ instanceof เบื้องต้น

ใช้ instanceof เพื่อตรวจสอบชนิดของวัตถุขณะทำงานก่อนดำเนินการแคสต์อย่างปลอดภัย

Object obj = "Hello, Java!";

if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.toUpperCase()); // HELLO, JAVA!
}

Object num = Integer.valueOf(42);
System.out.println(num instanceof Integer); // true
System.out.println(num instanceof String);  // false

instanceof กับการสืบทอด

instanceof จะคืนค่า true หากวัตถุนั้นเป็นอินสแตนซ์ของคลาส หรือคลาสย่อยใด ๆ ของคลาสนั้น (หรือเป็นอินสแตนซ์ของอินเทอร์เฟซที่วัตถุนั้นนำไปใช้)

class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

Animal a = new Dog();

System.out.println(a instanceof Animal); // true
System.out.println(a instanceof Dog);    // true
System.out.println(a instanceof Cat);    // false

การจับคู่รูปแบบด้วย instanceof (Java 16+)

Java 16 เพิ่ม การจับคู่รูปแบบสำหรับ instanceof ทำให้คุณประกาศตัวแปรที่ผูกค่าไว้ในนิพจน์เดียวกันได้ และไม่ต้องใช้การแคสต์อย่างชัดเจน

Object shape = "circle";

// Old way
if (shape instanceof String) {
    String s = (String) shape;
    System.out.println(s.length());
}

// New way (Java 16+) — binding variable 's' is in scope
if (shape instanceof String s) {
    System.out.println(s.length()); // 6
}

การจับคู่รูปแบบในเมธอด

การจับคู่รูปแบบทำให้การเลือกการทำงานตามชนิดข้อมูลเป็นระเบียบและปลอดภัย ตัวแปรที่ผูกค่าไว้จะอยู่ในขอบเขตเฉพาะบริเวณที่ทราบว่าเงื่อนไขเป็นจริง

sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}

static double area(Shape s) {
    if (s instanceof Circle c) {
        return Math.PI * c.radius() * c.radius();
    } else if (s instanceof Rectangle r) {
        return r.width() * r.height();
    }
    throw new IllegalArgumentException("Unknown shape");
}

System.out.println(area(new Circle(5)));         // 78.53...
System.out.println(area(new Rectangle(4, 6)));   // 24.0

instanceof กับ null

null instanceof AnyType จะคืนค่า false เสมอ และจะไม่ทำให้เกิดข้อผิดพลาด วิธีนี้ทำให้ instanceof เป็นวิธีตรวจสอบก่อนแคสต์ที่ปลอดภัยเมื่อค่าเป็น null

String s = null;
System.out.println(s instanceof String); // false (not NPE)

Object o = null;
if (o instanceof Number n) {
    System.out.println(n.intValue());
} else {
    System.out.println("Not a number (or null)"); // prints this
}

นิพจน์ switch และการจับคู่รูปแบบ

Java 21 ขยายการจับคู่รูปแบบไปยังนิพจน์ switch ทำให้สามารถกำหนดเส้นทางตามชนิดข้อมูลได้อย่างชัดเจนโดยไม่ต้องต่อเงื่อนไข if-else หลายชั้น

static String describe(Object obj) {
    return switch (obj) {
        case Integer i -> "Integer: " + i;
        case Double d  -> "Double: " + d;
        case String s  -> "String of length " + s.length();
        case null      -> "null value";
        default        -> "Unknown: " + obj.getClass().getSimpleName();
    };
}

System.out.println(describe(42));       // Integer: 42
System.out.println(describe(3.14));     // Double: 3.14
System.out.println(describe("hello")); // String of length 5
System.out.println(describe(null));     // null value

ClassCastException เมื่อไม่ใช้ instanceof

การแคสต์โดยไม่ตรวจสอบก่อนจะทำให้เกิด ClassCastException ขณะทำงาน ซึ่งเป็นข้อผิดพลาดที่พบได้บ่อยในรหัสรุ่นเก่า และการจับคู่รูปแบบช่วยป้องกันปัญหานี้ได้

Object obj = "I am a String";

try {
    Integer i = (Integer) obj; // ClassCastException!
} catch (ClassCastException e) {
    System.out.println("Cannot cast String to Integer");
}

// Safe version
if (obj instanceof Integer i) {
    System.out.println("Is integer: " + i);
} else {
    System.out.println("Not an integer");
}

เชิงปฏิบัติ: การประมวลผลรายการแบบผสม

กรณีใช้งานจริงคือการประมวลผลรายการวัตถุที่มีหลายชนิดด้วยการจับคู่รูปแบบ

import java.util.List;

List<Object> events = List.of(
    "User login", 42, 3.14, "Payment processed", 100
);

double numericSum = 0;
for (Object e : events) {
    if (e instanceof Integer n) numericSum += n;
    else if (e instanceof Double d) numericSum += d;
    else if (e instanceof String s) System.out.println("Log: " + s);
}
System.out.printf("Numeric sum: %.2f%n", numericSum); // 145.14

คลาสแบบปิดผนึกและการจับคู่ที่ครอบคลุม

คลาสแบบปิดผนึก (Java 17+) จะจำกัดว่าคลาสใดสามารถสืบทอดจากคลาสเหล่านั้นได้ เมื่อใช้ร่วมกับ switch ที่มีการจับคู่รูปแบบ คอมไพเลอร์จะตรวจสอบได้ว่าครอบคลุมทุกกรณีแล้ว จึงไม่จำเป็นต้องมีกรณีเริ่มต้น

sealed interface Notification permits EmailNotification, SmsNotification {}
record EmailNotification(String to, String body) implements Notification {}
record SmsNotification(String phone, String text) implements Notification {}

static void send(Notification n) {
    switch (n) {
        case EmailNotification e ->
            System.out.println("Email to " + e.to() + ": " + e.body());
        case SmsNotification s ->
            System.out.println("SMS to " + s.phone() + ": " + s.text());
        // no default needed — compiler knows all cases are covered
    }
}

รูปแบบที่มีเงื่อนไขกำกับ

การจับคู่รูปแบบรองรับ เงื่อนไขกำกับด้วย when (Java 21) เพื่อเพิ่มเงื่อนไขบูลีนควบคู่ไปกับการตรวจสอบชนิดข้อมูล

static String classify(Number n) {
    return switch (n) {
        case Integer i when i < 0  -> "negative int: " + i;
        case Integer i when i == 0 -> "zero";
        case Integer i             -> "positive int: " + i;
        case Double d              -> "double: " + d;
        default                    -> "other number";
    };
}

System.out.println(classify(-5));  // negative int: -5
System.out.println(classify(0));   // zero
System.out.println(classify(7));   // positive int: 7

ตรวจสอบอย่างรวดเร็ว

นิพจน์ต่อไปนี้คืนค่าอะไร

Object obj = null;
boolean result = obj instanceof String;
System.out.println(result);

สรุป: ตัวดำเนินการ instanceof

ประเด็นสำคัญ:

  • instanceof ตรวจสอบชนิดขณะทำงานและป้องกัน ClassCastException
  • คืนค่า false เมื่อเป็น null และจะไม่ทำให้เกิด NPE
  • คืนค่า true สำหรับคลาสนั้นเอง รวมถึงคลาสย่อยและอินเทอร์เฟซทั้งหมดของคลาสนั้น
  • การจับคู่รูปแบบด้วย instanceof ใน Java 16+: if (x instanceof String s) รวมการตรวจสอบและการแคสต์ไว้ในนิพจน์เดียว
  • switch ที่ใช้รูปแบบใน Java 21 ช่วยกำหนดเส้นทางตามชนิดข้อมูลได้อย่างเป็นระเบียบ พร้อมเงื่อนไขกำกับที่เลือกใช้ได้
  • คลาสแบบปิดผนึกและ switch ที่ครอบคลุมทุกกรณีทำให้ไม่จำเป็นต้องมีกรณีเริ่มต้น

คำถามที่พบบ่อย

บทเรียน “ตัวดำเนินการ instanceof” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัวดำเนินการ instanceof” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัวดำเนินการ instanceof”

ใช้ instanceof ตรวจสอบชนิดของออบเจ็กต์ก่อนแคสต์ และหลีกเลี่ยง ClassCastException คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “ตัวดำเนินการ instanceof” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ชนิดข้อมูลพื้นฐานกับชนิดข้อมูลอ้างอิง
  2. การแปลงชนิดข้อมูลแบบขยายและแบบหด
  3. ตัวดำเนินการ instanceof
  4. การแคสต์ชนิดข้อมูลในทางปฏิบัติ
← กลับไปที่ Java Academy