معالجة الأخطاء في Java: try/catch وما بعدها — دليل شامل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا تعتبر معالجة الأخطاء أمرًا حاسمًا لمطور Java

أي برنامج يتجاوز حدود "Hello, World!" سيواجه مواقف غير متوقعة: المستخدم يدخل حروفًا بدلاً من الأرقام، ملف غير موجود، الشبكة غير متاحة. في Java، تم تطوير آلية قوية وأنيقة للتعامل مع هذه الحالات وهي الاستثناءات (exceptions). معالجة الأخطاء بشكل صحيح ليست مجرد "تجاهل المشكلة"، بل بناء كود مستقر، قابل للتوقع وآمن.

في هذه المقالة، سنشرح ليس فقط البنية التقليدية try/catch، بل أيضًا التقنيات المتقدمة: try-with-resources، إنشاء استثناءات خاصة بك وأفضل الممارسات التي ستساعدك على كتابة كود احترافي بلغة Java.

1. الأساسيات: التسلسل الهرمي للاستثناءات وبنية try/catch/finally

قبل أن تلتقط الأخطاء، يجب أن تفهم طبيعتها. في Java، جميع الاستثناءات هي فئات فرعية من الكلاس Throwable. الفروع الرئيسية هي Exception (الاستثناءات التي يمكن ويجب معالجتها) و Error (أخطاء JVM الحرجة التي لا معنى لمعالجتها).

التقسيم الرئيسي داخل Exception هو إلى استثناءات checked (مفحوصة) و unchecked (غير مفحوصة).

  • Checked exceptions (مثل IOException, SQLException) — يجبرك المترجم على معالجتها. هذه أعطال خارجية متوقعة.
  • Unchecked exceptions (فئات فرعية من RuntimeException: NullPointerException, ArrayIndexOutOfBoundsException) — أخطاء في منطق البرنامج. لا يطلب المترجم معالجتها، لكن هذا لا يعني أنه يمكن تجاهلها.

البنية الأساسية try-catch-finally

الطريقة الأكثر شيوعًا للمعالجة هي كتلة try التي تحتوي على الكود "الخطير"، وكتلة أو أكثر من catch لالتقاط أنواع محددة من الاستثناءات.

import java.io.*;
public class ReadFileExample {
    public static void main(String[] args) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("data.txt"));
            String line = reader.readLine();
            System.out.println("تمت القراءة: " + line);
        } catch (FileNotFoundException e) {
            System.err.println("خطأ: الملف غير موجود! " + e.getMessage());
        } catch (IOException e) {
            System.err.println("خطأ إدخال/إخراج: " + e.getMessage());
        } finally {
            // finally يتم تنفيذه دائمًا، حتى في حالة وجود استثناء أو return
            try {
                if (reader != null) {
                    reader.close(); // من المهم إغلاق المورد
                }
            } catch (IOException e) {
                System.err.println("خطأ عند إغلاق الملف: " + e.getMessage());
            }
        }
    }
}

هام: كتلة finally ضرورية لتنظيف الموارد بشكل مضمون (إغلاق الملفات، اتصالات قاعدة البيانات). ومع ذلك، بدءًا من Java 7، ظهرت طريقة أكثر أناقة.

2. النهج الحديث: try-with-resources (Java 7+)

نسيان إغلاق ملف أو اتصال هو أحد أكثر الأخطاء شيوعًا للمبتدئين. بنية try-with-resources تغلق تلقائيًا جميع الموارد التي تطبق الواجهة AutoCloseable (أو Closeable). يصبح الكود أقصر وأنظف وأكثر أمانًا.

import java.io.*;
public class TryWithResourcesExample {
    public static void main(String[] args) {
        // يتم تعريف الموارد بين الأقواس بعد try
        try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"));
             BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {

            String line;
            while ((line = reader.readLine()) != null) {                

المدونات

توصيات الكتب