English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
في هذا الدرس، سنتعلم جملة try-with-resources لإغلاق المصادر تلقائيًا.
تغلق جملة try-with-resources جميع المصادر في نهاية الجملة. المصادر هي الأشياء التي يجب إغلاقها عند انتهاء البرنامج.
نحن نستخدم الجملة التالية كنحو:
try(resource declaration) { //استخدام المصدر } //كتلة catch {}
من خلال النظر في النحو، يمكننا إعلان جملة try-with-resources بالطريقة التالية:
إعلان وتInstantiationException للمصادر في جملة try.
تحديد ومعالجة جميع الاستثناءات التي قد تُطلق عند إغلاق المصادر.
ملاحظة:تغلق جملة try-with-resources جميع المصادر التي تنفذ واجهة AutoCloseable.
لنأخذ مثالاً على تنفيذ جملة try-with-resources.
import java.io.*; class Main { public static void main(String[] args) { String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { while ((line = br.readLine()) != null) { System.out.println(">>>\n"+line); {} } System.out.println("IOException في الكتلة try =>" + e.getMessage()); {} {} {}
إذا لم يتم العثور على ملف test.txt، يتم إخراجه.
استثناء IOException في كتلة try-with-resources => test.txt (لا يوجد ملف أو دليل)
إذا تم العثور على ملف test.txt، يتم إخراجه.
دخول كتلة try-with-resources السطر => السطر test
في هذا المثال، نستخدم مثيل BufferedReader لقراءة البيانات من ملف test.txt.
إعلان وتInstantiationException لـ BufferedReader في جملة try-with-resources يمكن التأكد من إغلاقها، سواء تم اكتمال جملة try بشكل طبيعي أو إطلاق استثناء.
يمكن استخدام كتلة معالجة الاستثناءات أوكلمة throwsمعالجتها.
في المثال السابق، يمكن إطلاق الاستثناءات في حالات ما من جملة try-with-resources:
لم يتم العثور على ملف test.txt.
إغلاق كائن BufferedReader.
يمكن أيضًا إطلاق استثنائية من جملة try، لأن قراءة الملف قد تفشل لأسباب متعددة في أي وقت.
إذا تم إطلاق استثنائين من كلا جملة try و try-with-resources، فإن استثنائية جملة try ستتم إطلاقها، واستثنائية جملة try-with-resources ستتم منعها.
في إصدارات Java 7 وما فوق، يمكن من خلال Throwable.getSuppressed() استدعاء هذه الطريقة من استثنائية تم إطلاقها من كتلة try لاسترجاع الاستثنائات الممنوعة.
هذا الطريقة تعود مصفوفة تحتوي على جميع الاستثنائات الممنوعة. نحصل على الاستثنائات الممنوعة في كتلة catch.
catch (IOException e) { System.out.println("استثنائية مرفوعة=>" + e.getMessage()); Throwable[] suppressedExceptions = e.getSuppressed(); for (int i = 0; i < suppressedExceptions.length; i++) { System.out.println("استثنائية ممنوعة=>" + suppressedExceptions[i]); {} {}
هذا هو ميزة استخدام try-with-resources:
قبل إدخال هذه الميزة في Java 7، كان علينا استخدام كتلة finally لضمان إغلاق الموارد لتجنب تسرب الموارد.
هذا يشبهبرنامج مثال 1. ولكن، في هذا البرنامج، نستخدم كتلة finally لإغلاق الموارد.
import java.io.*; class Main { public static void main(String[] args) { BufferedReader br = null; String line; try { System.out.println("دخول في كتلة try"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) { System.out.println(">>>\n"+line); {} } System.out.println("IOException في الكتلة try =>" + e.getMessage()); } finally { System.out.println("دخول الكتلة finally"); try { if (br != null) { br.close(); {} } System.out.println("IOException في الكتلة finally =>" + e.getMessage()); {} {} {} {}
نتائج الإخراج
دخول الكتلة try Line => line من ملف test.txt دخول الكتلة finally
من الممكن رؤية أن استخدام الكتلة finally لتنظيف الموارد يجعل الكود أكثر تعقيدًا.
هل لاحظتم جملة try ... catch في الكتلة finally؟ هذا لأن يمكن أن يحدث IOException عند إغلاق نموذج BufferedReader في الكتلة finally أيضًا، لذا تم أيضًا التقاطعه وتعامله.
تنفيذ جملة try-with-resourcesإدارة الموارد التلقائيةلا نحتاج إلى إغلاق الموارد بشكل صريح، لأن JVM ستبدأ في إغلاقها تلقائيًا. هذا يجعل الكود أكثر قراءة، وأسهل في الكتابة.
يمكننا استخدام try-with-resources باستخدام نقاط السطر لفصل موارد متعددة، مما يتيح إعلان موارد متعددة في جملة واحدة;
import java.io.*; import java.util.*; class Main { public static void main(String[] args) throws IOException { try (Scanner scanner = new Scanner(new File("testRead.txt"))) { PrintWriter writer = new PrintWriter(new File("testWrite.txt")) { while (scanner.hasNext()) { writer.print(scanner.nextLine()); {} {} {} {}
إذا لم يتم إنشاء أي استثناء عند تشغيل هذا البرنامج، فإن Scannerobject يقرأ سطرًا من ملف testRead.txt ويكتبه في ملف testWrite.txt الجديد.
عند إجراء عدة إعلانات، يتم إغلاق هذه الموارد في ترتيب عكسي. في هذا المثال، يتم إغلاق كائن PrintWriter أولاً، ثم إغلاق كائن Scanner.
في Java 7، هناك محدودة في جملة try-with-resources. يجب أن يتم إعلان الموارد في داخل الكتلة.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) { // code {}
إذا كنا نعلن عن الموارد في خارج الكتلة في Java 7، فإنه سيتم رفع رسالة خطأ.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) { // code {}
لحل هذا الخطأ، قام Java 9 بتحسين جملة try-with-resources حتى يمكن استخدامها حتى لو لم يتم إعلان مرجع الموارد المحلية. الآن سينفذ الكود ولن يرفع أي أخطاء في التجميع.