Try يشبه الشبكة ، التي تشير إلى جميع الاستثناءات التي ألقاها الرمز في Try {} ، ثم يسلم الاستثناءات إلى الكود في catch {} للمعالجة. أخيرا قم بتنفيذ الكود في النهاية. بغض النظر عما إذا كانت هناك استثناءات في الكود في المحاولة ، وما إذا كان المصيد يمسك بالاستثناء ، سيتم تنفيذ الكود في النهاية.
في حين أن معالجات مسبقات توفرها أنظمة فترة تنفيذ Java مفيدة لتصحيح الأخطاء ، فإنك ترغب عادة في التعامل مع الاستثناءات بنفسك. هناك مزايا للقيام بذلك: أولاً ، يتيح لك إصلاح الأخطاء. ثانياً ، يمكن أن يمنع البرنامج من الإنهاء تلقائيًا. عندما يحدث خطأ ، إذا توقف البرنامج وطباعة مسار المكدس ، فسيتم الخلط بين معظم المستخدمين. لحسن الحظ ، يمكنك بسهولة تجنب هذا الموقف.
للحذر من أخطاء فترة التنفيذ والتعامل معها ، ما عليك سوى وضع الرمز الذي تريد مراقبته في كتلة المحاولة. مباشرة بعد كتلة المحاولة ، حدد مثال التقاط خطأ نوع الاستثناء الذي تريد التقاطه في جملة Catch:
جرب {code ؛
على سبيل المثال:
استيراد java.io.*؛ // استدعاء حزمة io public class simplecharinout {public static void main (string args []) {char ch = '' ؛ // defining a حرف ch كـ 'system.out.prin tln (" أدخل حرفًا من فضلك ") ؛ // افتح أدخل حرفًا ، يرجى المحاولة على الشاشة {// يرجى وضع رمز البرنامج الذي تريد مراقبته في كتلة المحاولة. مباشرة بعد كتلة المحاولة ، حدد نمط الاستثناء الذي تريد التقاطه في جملة catch ch = (char) system.in.read () ؛ إذا كان هناك خطأ في الكود أعلاه ، فسوف تصطاد {} هنا ؛ // لا توجد عملية بعد نظام الخطأ. حرف الشاشة: // وقيمة CH}}
عندما نكتب Java Try .. Catch ، غالبًا ما نحتاج إلى إضافة بنود أخيرًا لإغلاق بعض موارد IO ، على سبيل المثال
InportStream IS ؛ Try {Is = OpenInputStream () ؛ }}
ولكن عند استخدام هذا النمط ، حتى قدامى المحاربين في جافا يرتكبون بعض الأخطاء أحيانًا. على سبيل المثال ، في الكود أعلاه ، عندما ترمي دالة OpenInputStream استثناءً أثناء التنفيذ ، فإن قيمة المتغير لا تزال خالية. لذلك لا يمكن القبض عليها بواسطة كتلة الصيد ، ولكن يتم إلقاؤها مباشرة إلى طبقة الاتصال. أنا شخصياً أعتقد أن الطريقة الأكثر أناقة للكتابة هي استدعاء طريقة IOUTILSILLISELISLISLE () التي توفرها حزمة Commons-IO بشكل مباشر لإغلاق الدفق (أو تغليف طريقة وثيقة () بنفسك).
هناك ميزة أخرى لاستخدام طريقة الكتابة هذه ، وهي أنه ليس من السهل ارتكاب أخطاء عند إغلاق موارد IO المتعددة ، مثل الرمز التالي:
inputStream Is ؛ OutputStream OS ؛ جرب {iS = OpenInputStream () ؛ إذا (OS! = NULL) OS.CLOSE () ؛
عندما يحدث خطأ في IS.Close () ، لا يمكن تنفيذ OS.Close () ، مما يؤدي إلى عدم إصدار المورد بواسطة OS.
ربما يعتقد Oracle أيضًا أن هذا النوع من المحاولة ... تمسك ... أخيرًا رمز Boilerplate غير ضروري للغاية ، لذلك قمت ببعض التعديلات على جملة Try في JDK 7 ، مما أدى تبدو أكثر إحكاما وأبسط. على سبيل المثال ، يمكن تغيير الرمز أعلاه إلى:
TRAW (inputStream is = OpenInputStream () ؛ OutputStream OS = OpenoutStream () ؛) {// افعل شيئًا} catch (ioException e) {eprintstacetrace (e) ؛}
يستدعي Oracle عبارة Try (..) هنا بيان المحاولة مع الموارد. تجدر الإشارة إلى أن الكائنات المشار إليها من قبل المتغيرات في المحاولة (..) يجب أن تكون حالات تنفذ واجهة Java.io.autoclosable. وهذا يعني أن المورد في عبارات المحاولة مع الموارد لا يقتصر على موارد IO.
من الضروري هنا تقديم بعض التفسيرات الإضافية للحصول على بعض تفاصيل بيان المحاولة مع الموارد:
يضمن JDK أن تسمى طريقة Close () لجميع الموارد بغض النظر عما إذا كانت طريقة Close () تلقي استثناءًا ، ويتم عكس ترتيب المكالمة من ترتيب إعلان الموارد.
سيتم اكتشاف جميع الاستثناءات التي تم طرحها في بيان المحاولة مع الموارد. إذا تم طرح استثناءات متعددة ، فسيتم قمع الاستثناء اللاحق. يمكن الحصول على الاستثناء المكبوت عن طريق استدعاء GetSuapressed () المحددة بواسطة فئة الرمي بدورها.
المثال أعلاه ،
عند الخروج من المحاولة. في الاستثناء الذي ألقاه OS.Close (). يمكنك الحصول على الاستثناء الذي تم إلقاؤه بواسطة IS.Close () من خلال طريقة GetUupressed ().
في حالة حدوث iOexception عند استدعاء OpenInputStream () ، فلن يتم استدعاء OpenOutputStream () ، لن يتم استدعاء Os.Close () و IS.Close () ، ولن يتمسك كتلة الصيد عند استثناء استثناء OpenInputStream ().
في حالة حدوث iOexception (يشار إليه بـ Token E1) ، فسيتم استدعاء is.close () الاستثناء الذي تم صيده بواسطة كتلة الصيد هو E1.
بالإضافة إلى إعادة تصميم كتلة المحاولة ، يقوم JDK 7 أيضًا بتبسيط جزء الصيد ، مما يسمح بدمج جمل الصيد المتعددة. على سبيل المثال:
Try (inputStream is = OpenInputStream () ؛ OutputStream Os = OpenoutStream () ؛) {// افعل شيئًا} catch (ioException | xmlparseException |
بالإضافة إلى ذلك ، عند إعادة تغريد استثناءات متعددة ، لم تعد بحاجة إلى تحديد نوع الاستثناء بالتفصيل. تحتاج فقط إلى إعلان الاستثناء الذي يجب إلقاؤه عند تحديد الطريقة. على سبيل المثال
// على الرغم من أن الاستثناء يستخدم هنا لمطابقة IOException ، فإن المترجم يعرف أن الاستثناء الذي تم طرحه بالفعل على الطبقة العليا هو IoException public void doio () يلقي IoException {try {throw new ioexception () ؛ ) {رمي e ؛
ملاحظة: لا يمكنني التفكير في أي فوائد ستجلبها هذه الميزة
يحتوي JDK 7 على ميزات بناء جملة جديدة مثيرة للاهتمام ، مثل الحرفية الثنائية ، وتجزئة الأرقام الطويلة مع السفقة ، وتكنولوجيا الاستدلال للمعلمات العامة ، ويدعم التبديل مطابقة السلسلة ، إلخ. الآن قدمت JDK 8 بعض الميزات المفيدة. دون النظر في التوافق المتخلف ، يمكن أن يجعل بعض ميزات بناء الجملة المناسبة والتطبيق مرنًا رمزنا أكثر وضوحًا وأكثر إيجازًا إلى حد ما.