0Pricing
Java Academy · درس

العامل instanceof

استخدم instanceof للتحقق من أنواع الكائنات قبل إجراء التحويل وتجنب ClassCastException

العامل instanceof درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 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 المعتمد على مطابقة الأنماط، يستطيع المصرّف التحقق من شمول جميع الحالات، فلا تكون هناك حاجة إلى حالة default.

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 للصنف نفسه ولجميع أصنافه الفرعية وواجهاته
  • مطابقة الأنماط في Java 16 فأحدث: يجمع if (x instanceof String s) بين التحقق والتحويل النوعي
  • يوجّه switch المعتمد على الأنماط في Java 21 التنفيذ بوضوح حسب النوع، مع إمكانية إضافة شروط حراسة
  • تلغي الأصناف المحكَمة مع switch الشامل الحاجة إلى حالة default

الأسئلة الشائعة

هل درس «العامل instanceof» مجاني؟

نعم — نص درس «العامل instanceof» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «العامل instanceof»؟

استخدم instanceof للتحقق من أنواع الكائنات قبل إجراء التحويل وتجنب ClassCastException تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «العامل instanceof»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الأنواع البدائية مقابل الأنواع المرجعية
  2. تحويلات التوسيع والتضييق
  3. العامل instanceof
  4. تحويل الأنواع عمليًا
← العودة إلى Java Academy