نمط Try With Resources
جزء من قسم البرمجة كائنية التوجه في رحلة Java على Coddy. الدرس 62 من 87.
عند العمل مع موارد مثل تدفقات file أو اتصالات connection، يجب عليك دائمًا إغلاقها عند الانتهاء. وإلا فإنك تخاطر بتسريبات الذاكرة. يستخدم approach التقليدي كتلة finally، لكنه مطوّل ومعرّض للأخطاء.
تغلق عبارة try-with-resources في Java الموارد تلقائيًا عند اكتمال block. يمكن استخدام أي class implements واجهة 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();
} // يتم الإغلاق تلقائياً هنايمكنك إدارة الموارد Multiple عن طريق فصلها بفواصل منقوطة. ويتم إغلاقها بترتيب عكسي للإعلان عنها:
try (FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr)) {
// استخدم كلا الموردين
} // يُغلق br أولاً، ثم frلإنشاء فئة AutoCloseable خاصة بك، نفّذ الواجهة AutoCloseable وطريقتها الوحيدة close():
public class DatabaseConnection implements AutoCloseable {
public DatabaseConnection() {
System.out.println("Connection opened");
}
@Override
public void close() {
System.out.println("Connection closed");
}
}يضمن هذا النمط تحرير الموارد بشكل صحيح دائمًا، حتى في حال حدوث استثناءات أثناء المعالجة.
التحدي
سهللنبنِ نظامًا لإدارة الموارد يوضّح قوة try-with-resources! ستنشئ فئات مخصّصة قابلة للإغلاق تلقائيًا تحاكي إدارة الاتصالات والجلسات، مع ضمان تنظيفها دائمًا بطريقة صحيحة.
ستُنظّم الشيفرة الخاصة بك عبر ثلاثة ملفات:
Connection.java: أنشئ فئة تحاكي اتصالًا بقاعدة بيانات. يجب أن تطبّق فئةConnectionالواجهةAutoCloseable. وتحتاج إلىfieldخاص لاسم الاتصال (String)، وconstructorيأخذ الاسم ويطبع[name] connection opened، وmethodباسمquery(String sql)يطبعExecuting on [name]: [sql]، وmethodclose()المطلوب الذي يطبع[name] connection closed.Session.java: أنشئ فئة أخرى قابلة للإغلاق تلقائيًا تحاكي جلسة مستخدم. يجب أن تطبّق فئةSessionأيضًا الواجهةAutoCloseable. أضِفfieldخاصًا لاسم المستخدم (String)، وconstructorيأخذ اسم المستخدم ويطبعSession started for [username]، وmethodباسمperformAction(String action)يطبع[username] performed: [action]، وmethodباسمclose()يطبعSession ended for [username].Main.java: اجمع نظام إدارة الموارد الخاص بك! ستتلقى ثلاث مدخلات: اسم اتصال، واسم مستخدم، وactionلتنفيذه.أولًا، أظهِر إدارة مورد واحد. اطبع
=== Single Resource ===، ثم استخدم try-with-resources لإنشاءConnectionبالاسم المعطى. Inside كتلة try، استدعِquery("SELECT * FROM users"). يجب أن يُغلق الاتصال تلقائيًا عند انتهاء الكتلة.بعد ذلك، أظهِر إدارة موارد متعددة. اطبع سطرًا فارغًا، ثم
=== Multiple Resources ===. استخدم try-with-resources مع كلٍّ منConnection(باستخدام الاسم نفسه) وSession(باستخدام اسم المستخدم)، مع التصريح عنهما بهذا الترتيب باستخدام الفواصل المنقوطة. Inside كتلة try، استدعِ أولًاquery("INSERT INTO logs")على الاتصال، ثم استدعِperformActionمعinputaction على الجلسة. لاحظ كيف تُغلق الموارد بترتيب عكسي!
ستتلقى ثلاث مدخلات بالترتيب: اسم الاتصال (String)، واسم المستخدم (String)، وaction (String).
لاحظ كيف يلغي try-with-resources الحاجة إلى استدعاءات close الصريحة وكتل 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();
// === Single Resource ===
// TODO: اطبع العنوان
// TODO: استخدم try-with-resources لإنشاء Connection
// TODO: Inside the try block, call query("SELECT * FROM users")
// === Multiple Resources ===
// TODO: اطبع سطرًا فارغًا والعنوان
// TODO: استخدم try-with-resources مع كل من Connection و Session
// TODO: داخل كتلة try:
// - Call query("INSERT INTO logs") on the connection
// - استدعِ performAction مع إجراء الإدخال action على session
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات الـ OOP
الملفات الخارجيةمقدمة في الـ OOPالفئات (Classes) مقابل الكائنات (Objects)الكلمة المفتاحية thisالدوال (Methods)الحقول (Attributes)دالة البناء (Constructor)تعدد أشكال دالة البناء (Constructor Overloading)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسية (extends)الكلمة المفتاحية superإعادة تعريف الدوال (@Override)تسلسل المنشئات (Constructor Chaining)كلاس Objectالوراثة الأحادية ومتعددة المستوياتلماذا لا توجد وراثة متعددة للكلاساتمراجعة - هيكلية الموظفين7الدوال الخاصة وفئة Object
دالة toString()equals() و hashCode()دالة clone()compareTo() و Comparableواجهة Comparatorمراجعة - الترتيب المخصص10معالجة الاستثناءات في OOP
التسلسل الهرمي لفئات الاستثناءاتالاستثناءات المخصصةالأخطاء من نوع Checked مقابل Uncheckedنمط Try With Resourcesمراجعة - Validated User2محددات الوصول والتغليف
نظرة عامة على مستويات الوصولدوال Getter و Setterإخفاء البياناتالكلمة المفتاحية finalمراجعة - مدير الحساب البنكي5تعدد الأشكال (Polymorphism)
أساسيات الـ Method Overloadingالـ Method Overriding (في وقت التشغيل)الـ Upcasting والـ Downcastingمعامل الـ instanceofالفئات والدوال المجردة (Abstract)مراجعة - حاسبة الأشكال8مفاهيم OOP المتقدمة
الـ Composition مقابل الـ Inheritanceالـ Aggregation مقابل الـ Compositionالفئات الداخلية والمتداخلة والمجهولة (Inner, Nested & Anonymous)الـ Enums ودوالهاالـ Records (Java 16+)الـ Sealed Classes (Java 17+)11أنماط التصميم - الجزء الأول
مقدمة في أنماط التصميمنمط Singletonنمط Factoryنمط Builderنمط Observerنمط Strategy3خصائص الفئة والعضو الساكن
المتغيرات الخاصة بالكائن مقابل المتغيرات الساكنةالدوال الساكنةالكتل البرمجية الساكنةالثوابت (static final)ملخص - العداد والأدوات المساعدة6الواجهات (Interfaces) والأصناف المجردة (Abstract Classes)
مقدمة في الواجهات (Interfaces)تنفيذ الواجهات (Interfaces)تنفيذ واجهات متعددةالـ Default و Static في الواجهاتالأصناف المجردة مقابل الواجهاتالواجهات الوظيفية (Functional Interfaces)مراجعة - نظام الدفع9الأنواع العامة (Generics)
مقدمة في الأنواع العامةالأصناف العامة (Generic Classes)الدوال العامة (Generic Methods)معاملات الأنواع المقيدةالرموز البديلة (?, extends, super)مراجعة - الحاويات العامة12أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المكررتدرّب بنفسك: مترجم Java عبر الإنترنت