هل يتم تنفيذ finally دائمًا في Java؟ تحليل كامل مع كود

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

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

ابدأ الدورة

كتلة finally في Java: خرافات، واقع ومزالق

\n\n

كل مطور Java، من المبتدئ إلى الخبير، يواجه عاجلاً أم آجلاً كتلة finally. في الكتب المدرسية يُكتب: "يتم تنفيذ هذه الكتلة دائمًا، بغض النظر عن حدوث استثناء أم لا". يبدو وكأنه ضمان حديدي، أليس كذلك؟ لكن دعونا نلقي نظرة خلف الكواليس.

\n\n

على StackOverflow، سؤال "هل يتم تنفيذ كتلة finally دائمًا في Java؟" حصد آلاف المشاهدات ومئات التعليقات. المبرمجون ذوو الخبرة يتجادلون، والمبتدئون يضيعون، والحالات الواقعية تُظهر: "دائمًا" ليست حقيقة مطلقة. في هذه المقالة، سنحلل جميع السيناريوهات، ونكتب كودًا حقيقيًا، ونكتشف متى قد يخذلكم finally.

\n\n

كيف يعمل finally؟ مثال أساسي

\n\n

في البداية - الكلاسيكي. تُستخدم كتلة finally لتحرير الموارد: إغلاق الملفات، اتصالات قواعد البيانات، المقابس (sockets). يتم تنفيذها بعد try (و catch، إذا كان هناك استثناء)، ولكن قبل أن يغادر التحكم الدالة.

\n\n
public class FinallyDemo {\n    public static void main(String[] args) {\n        try {\n            System.out.println("داخل try");\n            int result = 10 / 2; // كل شيء جيد\n        } catch (ArithmeticException e) {\n            System.out.println("تم التقاط الاستثناء: " + e.getMessage());\n        } finally {\n            System.out.println("تم تنفيذ كتلة finally!");\n        }\n        System.out.println("البرنامج يستمر...");\n    }\n}
\n\n

الإخراج:

\n
داخل try\nتم تنفيذ كتلة finally!\nالبرنامج يستمر...
\n\n

كل شيء متوقع. لكن ماذا سيحدث إذا نشأ استثناء في try لم يتم التقاطه؟

\n\n
public class FinallyWithUncaught {\n    public static void main(String[] args) {\n        try {\n            System.out.println("محاولة القسمة على صفر...");\n            int result = 10 / 0; // استثناء!\n        } finally {\n            System.out.println("يتم تنفيذ finally قبل أن يطير الاستثناء للأعلى");\n        }\n        // هذا السطر لن يتم تنفيذه\n        System.out.println("هذا السطر لن يُطبع");\n    }\n}
\n\n

الإخراج سيفاجئ المبتدئين:

\n
محاولة القسمة على صفر...\nيتم تنفيذ finally قبل أن يطير الاستثناء للأعلى\nException in thread "main" java.lang.ArithmeticException: / by zero\n    at FinallyWithUncaught.main(FinallyWithUncaught.java:5)
\n\n

تم تنفيذ كتلة finally، على الرغم من أن الاستثناء لم يتم معالجته. هذا السلوك هو ما ولّد خرافة "دائمًا". لكن دعونا نتعمق أكثر.

\n\n

متى لا يتم تنفيذ finally؟ سيناريوهات حقيقية

\n\n

هناك على الأقل ثلاث حالات قد لا يتم فيها تنفيذ finally. احفظوها - ستوفر عليكم ساعات من التصحيح.

\n\n

1. System.exit() - إنهاء JVM بشكل طارئ

\n\n

الحالة الأكثر شهرة. إذا تم استدعاء System.exit(0) داخل كتلة try، تنتهي JVM فورًا، ولن يتم تنفيذ finally.

\n\n
public class FinallyAndExit {\n    public static void main(String[] args) {\n        try {\n            System.out.println("نبدأ العمل...");\n            System.exit(0); // تنتهي JVM هنا\n        } finally {\n            // هذا الكود لن يتم تنفيذه!\n            System.out.println("هل ظننتم أنني سأُنفذ؟ لا!");\n        }\n    }\n}
\n\n

الإخراج:

\n
نبدأ العمل...
\n\n

لماذا؟ لأن System.exit() يوقف الآلة الافتراضية على مستوى نظام التشغيل. هذا ليس استثناءً - بل أمر "بالموت". كتلة finally ببساطة لا يتوفر لها الوقت للعمل.

\n\n
\n مهم: إذا كنت تستخدم System.exit() في الكود، توقف. هذا أسلوب سيء. لإنهاء البرنامج، استخدم

المدونات

توصيات الكتب