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

نمط Try With Resources

جزء من قسم Object Oriented Programming في رحلة Java على Coddy — الدرس 62 من 87.

عند العمل مع موارد مثل تدفقات الملفات أو اتصالات قاعدة البيانات، يجب عليك دائمًا إغلاقها عند الانتهاء—وإلا فإنك تخاطر بحدوث تسرب في الذاكرة. يستخدم النهج التقليدي كتلة finally، لكنه مطول وعرضة للأخطاء.

بيان try-with-resources في Java يغلق الموارد تلقائيًا عند اكتمال الكتلة البرمجية. أي فئة (class) تقوم بتنفيذ واجهة AutoCloseable يمكن استخدامها مع هذا النحو البرمجي:

// النهج التقليدي - مطول ومحفوف بالمخاطر
BufferedReader reader = null;
try {
    reader = new BufferedReader(new FileReader("file.txt"));
    String line = reader.readLine();
} finally {
    if (reader != null) {
        reader.close();  // قد يرمي استثناءً أيضاً!
    }
}

// Try-with-resources - نظيف وآمن
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    String line = reader.readLine();
}  // يتم الإغلاق تلقائياً هنا

يمكنك إدارة موارد متعددة عن طريق الفصل بينها بفاصلة منقوطة. يتم إغلاقها بترتيب عكسي لترتيب التصريح عنها:

try (FileReader fr = new FileReader("input.txt");
     BufferedReader br = new BufferedReader(fr)) {
    // استخدم كلا الموردين
}  // يتم إغلاق br أولاً، ثم fr

لإنشاء فئة (class) خاصة بك قابلة للإغلاق تلقائيًا، قم بتنفيذ واجهة AutoCloseable وطريقتها close() الوحيدة:

public class DatabaseConnection implements AutoCloseable {
    public DatabaseConnection() {
        System.out.println("Connection opened");
    }
    
    @Override
    public void close() {
        System.out.println("Connection closed");
    }
}

يضمن هذا النمط تحرير الموارد بشكل صحيح دائمًا، حتى في حالة حدوث استثناءات أثناء المعالجة.

challenge icon

التحدي

سهل

لنقم ببناء نظام لإدارة الموارد يوضح قوة try-with-resources! ستقوم بإنشاء فئات مخصصة قابلة للإغلاق تلقائيًا (auto-closeable) تحاكي إدارة الاتصالات والجلسات، مما يضمن تنظيفها دائمًا بشكل صحيح.

ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:

  • Connection.java: أنشئ فئة تحاكي اتصال قاعدة البيانات. يجب أن تنفذ فئة Connection واجهة AutoCloseable. تحتاج إلى حقل خاص لاسم الاتصال (String)، ومنشئ (constructor) يأخذ الاسم ويطبع [name] connection opened، وطريقة query(String sql) تطبع Executing on [name]: [sql]، وطريقة close() المطلوبة التي تطبع [name] connection closed.
  • Session.java: أنشئ فئة أخرى قابلة للإغلاق تلقائيًا تحاكي جلسة مستخدم. يجب أن تنفذ فئة Session أيضًا واجهة AutoCloseable. قم بتضمين حقل خاص لاسم المستخدم (String)، ومنشئ يأخذ اسم المستخدم ويطبع Session started for [username]، وطريقة performAction(String action) تطبع [username] performed: [action]، وطريقة close() تطبع Session ended for [username].
  • Main.java: اجمع نظام إدارة الموارد الخاص بك معًا! ستتلقى ثلاثة مدخلات: اسم الاتصال، واسم المستخدم، والإجراء المراد تنفيذه.

    أولاً، قم بتوضيح إدارة مورد واحد. اطبع === Single Resource ===، ثم استخدم try-with-resources لإنشاء Connection بالاسم المعطى. داخل كتلة try، استدعِ query("SELECT * FROM users"). يجب أن يُغلق الاتصال تلقائيًا عند انتهاء الكتلة.

    بعد ذلك، قم بتوضيح موارد متعددة. اطبع سطرًا فارغًا، ثم === Multiple Resources ===. استخدم try-with-resources مع كل من Connection (باستخدام نفس الاسم) و Session (باستخدام اسم المستخدم)، مع التصريح عنهما بهذا الترتيب باستخدام الفواصل المنقوطة. داخل كتلة try، استدعِ أولاً query("INSERT INTO logs") على الاتصال، ثم استدعِ performAction مع إجراء الإدخال على الجلسة. راقب كيف تُغلق الموارد بترتيب عكسي!

ستتلقى ثلاثة مدخلات بالترتيب: اسم الاتصال (String)، واسم المستخدم (String)، والإجراء (String).

لاحظ كيف تلغي try-with-resources الحاجة إلى استدعاءات الإغلاق الصريحة وكتل finally. الموارد مضمونة الإغلاق حتى في حالة حدوث استثناءات، وتُغلق الموارد المتعددة بترتيب عكسي للتصريح عنها!

جرّب بنفسك

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String connectionName = scanner.nextLine();
        String username = scanner.nextLine();
        String action = scanner.nextLine();
        
        // === مورد واحد ===
        // TODO: اطبع الترويسة
        // TODO: استخدم try-with-resources لإنشاء Connection
        // TODO: داخل كتلة try، استدعِ query("SELECT * FROM users")
        
        // === موارد متعددة ===
        // TODO: اطبع سطراً فارغاً والترويسة
        // TODO: استخدم try-with-resources مع كل من Connection و Session
        // TODO: داخل كتلة try:
        //       - استدعِ query("INSERT INTO logs") على الـ connection
        //       - استدعِ performAction مع action المدخل على الـ session
        
    }
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming