Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الأخطاء من نوع Checked مقابل Unchecked

جزء من قسم البرمجة كائنية التوجه في رحلة Java على Coddy. الدرس 61 من 87.

لقد رأيت أن تسلسل Java الهرمي لـ exceptions ينقسم إلى فروع مختلفة. والتمييز الأساسي الذي تحتاج إلى فهمه هو بين checked وunchecked exceptions. ويؤثر ذلك في كيفية وجوب handle لها في شفرتك.

Checked exceptions هي exceptions التي يُجبرك المترجم على handleها. وهي تمتد إلى Exception directly (وليس من خلال RuntimeException). يجب عليك إما catchها أو declareها باستخدام throws:

// يجب معالجة IOException - فهو مفحوص
public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path);  // قد يطلق IOException
}

// أو التقاطه
public void readFileSafe(String path) {
    try {
        FileReader reader = new FileReader(path);
    } catch (IOException e) {
        System.out.println("File error: " + e.getMessage());
    }
}

تُمدِّد الاستثناءات غير المُتحقَّق منها RuntimeException. لا ي要求 منك المترجم التعامل معها. وهي تشير عادةً إلى أخطاء برمجية مثل المراجع الفارغة أو الوصول غير الصالح إلى المصفوفات:

// لا يلزم الإعلان عن throws
public int divide(int a, int b) {
    return a / b;  // قد يرمي ArithmeticException (غير مفحوص)
}

String name = null;
name.length();  // NullPointerException (غير مفحوص)

عند إنشاء exceptions مخصصة، اختر الفئة الأصلية بناءً على الطريقة التي تريد من المتصلين بها handle هذه exceptions. استخدم checked exceptions للحالات القابلة للاسترداد التي ينبغي للمتصل توقّعها. استخدم exceptions غير المُتحقَّق منها لأخطاء البرمجة التي لا ينبغي أن تحدث في code صحيح.

challenge icon

التحدي

سهل

لنَبْنِ نظامًا للتحقق من العمر يوضّح الفرق الأساسي بين الاستثناءات checked وunchecked! ستنشئ استثناءات مخصّصة من كلا النوعين، وسترى كيف يتعامل معها المصرّف بشكل مختلف.

ستنظّم الكود في أربعة ملفات:

  • InvalidAgeException.java: أنشئ استثناءً checked لفشل التحقق من العمر. يجب أن يمدّد هذا الاستثناء Exception مباشرةً، ما يعني أن Callers سيُجبرون على التعامل معه. أضف constructor يقبل message ويمرّره إلى parent class.
  • NegativeAgeException.java: أنشئ استثناءً unchecked عندما يقدّم شخص ما عمرًا سالبًا (وهو خطأ برمجي لا ينبغي أن يحدث مع إدخال صحيح). يجب أن يمدّد هذا الاستثناء RuntimeException. أضف constructor يقبل message ويمرّره إلى parent.
  • AgeVerifier.java: أنشئ class يتحقق من الأعمار باستخدام نوعَي exception. أضف طريقتين static:

    verifyAge(int age) - يجب أن ترمي هذه الطريقة NegativeAgeException (unchecked) مع message "Age cannot be negative: [age]" إذا كان العمر أقل من 0. وإذا كان العمر أقل من 18، فارْمِ InvalidAgeException (checked) مع message "Must be 18 or older: [age]". وإلا، اطبع Age [age] verified successfully. وبما أن هذه الطريقة ترمي exception checked، يجب أن تعلن عنه باستخدام throws InvalidAgeException.

    verifyAgeUncheckedOnly(int age) - تستخدم هذه الطريقة exceptions من نوع unchecked فقط. إذا كان العمر سالبًا، فارْمِ NegativeAgeException بالتنسيق نفسه للرسالة. وإذا كان العمر أقل من 18، فارْمِ IllegalArgumentException مع message "Too young: [age]". وإلا، اطبع Age [age] verified (unchecked method). لاحظ أن هذه الطريقة لا تحتاج إلى إعلان throws!

  • Main.java: اجمع نظام التحقق الخاص بك! ستتلقى input واحدًا: عمرًا (عددًا صحيحًا).

    أولًا، اطبع === Checked Exception Method === واستدعِ verifyAge باستخدام عمر الإدخال. وبما أنها ترمي exception checked، يجب أن تضع الاستدعاء داخل try-catch. التقط InvalidAgeException واطبع Checked exception caught: [message]. والتقط أيضًا NegativeAgeException واطبع Unchecked exception caught: [message].

    ثم اطبع سطرًا فارغًا و=== Unchecked Exception Method ===. استدعِ verifyAgeUncheckedOnly باستخدام العمر نفسه. رغم أن هذه الطريقة قد ترمي exceptions، فلستَ مُجبرًا على التقاطها. ومع ذلك، ضعها داخل try-catch على أي حال للتعامل مع الأخطاء بسلاسة. التقط NegativeAgeException واطبع Runtime exception caught: [message]. والتقط IllegalArgumentException واطبع Illegal argument caught: [message].

ستتلقى input واحدًا: عددًا صحيحًا يمثّل العمر المراد التحقق منه.

لاحظ الفرق الأساسي: الطريقة التي تستخدم exception من نوع checked تتطلب إعلان throws وتجبر Callers على التعامل معه، بينما تُصرَّف الطريقة unchecked بشكل صحيح من دون أي معالجة لـ exception. هذا هو الفرق الجوهري بين exceptions من نوع checked وunchecked في Java!

جرّب بنفسك

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int age = scanner.nextInt();
        
        // TODO: Test the checked exception method
        // Print: "=== Checked Exception Method ==="
        // قم باستدعاء AgeVerifier.verifyAge(age) في try-catch
        // - Catch InvalidAgeException: print "Checked exception caught: [message]"
        // - Catch NegativeAgeException: print "Unchecked exception caught: [message]"
        
        
        // TODO: Print a blank line, then "=== Unchecked Exception Method ==="
        // قم باستدعاء AgeVerifier.verifyAgeUncheckedOnly(age) في try-catch
        // - Catch NegativeAgeException: print "Runtime exception caught: [message]"
        // - Catch IllegalArgumentException: print "Illegal argument caught: [message]"
        
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Java عبر الإنترنت