1. مقدمة
حاول ... التقاط ... أخيرًا على الأرجح جملة يعرفها الجميع ، وهي بسيطة للغاية للاستخدام ، ويبدو من السهل فهمها منطقياً. ومع ذلك ، أخبرني "التعلم" الذي واجهته شخصيًا أن هذا الشيء ليس بسيطًا ومطيعًا كما تخيلت. لا تصدق ذلك؟ ثم انظر إلى الكود أدناه ، ماذا ستكون النتيجة بعد تنفيذها؟ لا تنظر إلى الإجابات للخلف ، ولا تسمح بتنفيذ التعليمات البرمجية لرؤية الإجابات الحقيقية. إذا كانت إجابتك صحيحة ، فلن تضطر إلى إضاعة الوقت في قراءة هذه المقالة.
اختبار الحزمة الفئة العامة testException {public testException () {} testex boolean () يلقي الاستثناء {boolean ret = true ؛ حاول {ret = testEx1 () ؛ } catch (استثناء e) {system.out.println ("testex ، استثناء catch") ؛ ret = false ؛ رمي ه ؛ } أخيرًا {system.out.println ("testex ، أخيرًا ؛ قيمة الإرجاع =" + ret) ؛ العودة ret. }} boolean testex1 () يلقي الاستثناء {boolean ret = true ؛ حاول {ret = testEx2 () ؛ if (! ret) {return false ؛ } system.out.println ("testex1 ، في نهاية المحاولة") ؛ العودة ret. } catch (استثناء e) {system.out.println ("testex1 ، استثناء catch") ؛ ret = false ؛ رمي ه ؛ } أخيرًا {system.out.println ("testEx1 ، أخيرًا ؛ return value =" + ret) ؛ العودة ret. }} boolean testex2 () يلقي الاستثناء {boolean ret = true ؛ حاول {int b = 12 ؛ int c ؛ لـ (int i = 2 ؛ i> = -2 ؛ i--) {c = b / i ؛ System.out.println ("i =" + i) ؛ } إعادة صواب ؛ } catch (استثناء e) {system.out.println ("testEx2 ، استثناء catch") ؛ ret = false ؛ رمي ه ؛ } أخيرًا {system.out.println ("testEx2 ، أخيرًا ؛ return value =" + ret) ؛ العودة ret. }} public static void main (string [] args) {testException testException1 = new testException () ؛ حاول {testException1.testex () ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ }}} ما هو إجابتك؟ هل هو الجواب أدناه؟
أنا = 2
أنا = 1
testex2 ، استثناء استثناء
testex2 ، أخيرًا ؛ قيمة الإرجاع = خطأ
Testex1 ، استثناء التقاط
testex1 ، أخيرًا ؛ قيمة الإرجاع = خطأ
Testex ، استثناء استثناء
Testex ، أخيرًا ؛ قيمة الإرجاع = خطأ
إذا كانت إجابتك بالفعل كما هو مذكور أعلاه ، فأنت مخطئ. ^_^، ثم أقترح عليك قراءة هذه المقالة بعناية أو استخدم الكود أعلاه لتعديل وتنفيذ واختبارها وفقًا لمواقف مختلفة. ستجد أن هناك أشياء كثيرة ليست بسيطة كما يتخيل في الأصل. الآن نشر الإجابة الصحيحة:
أنا = 2
أنا = 1
testex2 ، استثناء استثناء
testex2 ، أخيرًا ؛ قيمة الإرجاع = خطأ
testex1 ، أخيرًا ؛ قيمة الإرجاع = خطأ
Testex ، أخيرًا ؛ قيمة الإرجاع = خطأ
ملحوظة:
أخيرًا ، يجب ألا تظهر كتلة البيان ، يجب أن تظهر العودة. ويفضل أن يكون RETUR RET أعلاه عبارة أخرى للتعامل مع المنطق ذي الصلة.
2. جافا استثناء
تشير الاستثناءات إلى المواقف المختلفة التي تحدث بشكل غير متوقع ، مثل: الملف غير الموجود ، وفشل اتصال الشبكة ، والمعلمات غير القانونية ، وما إلى ذلك. الاستثناء هو حدث يحدث أثناء تشغيل البرنامج ويتداخل مع تدفق التعليمات العادية. يصف Java استثناءات مختلفة من خلال العديد من الفئات الفرعية من فئة الرمي في API. لذلك ، فإن استثناءات Java هي كائنات ، ومثيلات من الفئات الفرعية القابلة للرمي ، تصف شروط الخطأ التي تظهر في الترميز. عند إنشاء شرط ، سوف يرمي الخطأ استثناء.
رسم تخطيطي للتسلسل الهرمي لصف فئة جافا:
الشكل 1 الشكل 1 جافا مخطط التسلسل الهرمي
في Java ، جميع الاستثناءات لها سلف مشترك ، يمكن رميه (قابلة للرمي). يحدد رمي القاسم المشترك لأي مشاكل يمكن أن تنتقل من خلال تطبيقات Java في الكود من خلال آليات انتشار الاستثناء.
رمي: هناك فئتان فرعيتان مهمتان: الاستثناء والخطأ. كلاهما فئات فرعية مهمة لمعالجة استثناءات Java ، ويحتوي كل منهما على عدد كبير من الفئات الفرعية.
خطأ: خطأ لا يمكن للبرنامج التعامل معه ، مما يشير إلى وجود مشكلة خطيرة في تشغيل التطبيق. لا ترتبط معظم الأخطاء بالإجراءات التي يقوم بها كاتب الكود ، ولكنها تمثل مشاكل مع JVM (الجهاز الظاهري Java) عند تشغيل الرمز. على سبيل المثال ، يقوم جهاز Java Virtual بتشغيل خطأ (MachineReror الظاهري) ، وسيظهر OutofMemoryerror عندما لم يعد JVM لديه موارد الذاكرة اللازمة لمواصلة العملية. عند حدوث هذه الاستثناءات ، يختار الجهاز الظاهري Java (JVM) عمومًا إنهاء المواضيع.
تشير هذه الأخطاء إلى أن الفشل يحدث عندما يكون الجهاز الظاهري نفسه ، أو عندما يحاول الجهاز الظاهري تنفيذ التطبيق ، مثل خطأ تشغيل الجهاز الظاهري Java (MachineRror الظاهري) ، وخطأ في تعريف الفئة (noclassDeffounderror) ، وما إلى ذلك. هذه الأخطاء غير قابلة للتحقيق لأنها خارج عن قدرة التحكم ومعالجة التطبيق ، ومعظمها لا يتم تشغيلها. لتطبيق مصمم جيدًا ، حتى في حالة حدوث خطأ ، فإنه لا ينبغي أن يحاول بشكل أساسي التعامل مع الاستثناءات التي تسببها. في Java ، يتم وصف الخطأ بواسطة فئة فرعية من الخطأ.
استثناء: استثناء من أن البرنامج نفسه يمكنه التعامل معه.
فئة الاستثناء لديها فئة فرعية مهمة ، RunTimeException. تمثل فئة RunTimeException وفئاته الفرعية خطأًا أثاره "عمليات JVM المشتركة". على سبيل المثال ، إذا حاولت استخدام مرجع كائن فارغ ، أو مقسوم أو صفر خارج الحدود ، واستثناء وقت التشغيل (NullPointerException ، ArithMeticexception) و ArrayIndExoutofBoundException يتم رفعها على التوالي.
ملاحظة: الفرق بين الاستثناءات والأخطاء: يمكن التعامل مع الاستثناءات من قبل البرنامج نفسه ، ولكن لا يمكن التعامل مع الأخطاء.
بشكل عام ، يتم تقسيم استثناءات Java (بما في ذلك الاستثناء والخطأ) إلى استثناءات محددة واستثناءات غير محددة.
يمكن التحقق من الاستثناءات (الاستثناءات التي يجب معالجتها من قبل المترجم): من السهل أن تحدث ومعقولة ومتسامحة عند تشغيل البرنامج الصحيح. على الرغم من أن الاستثناء القابل للتحقق هو حالة غير طبيعية ، إلا أن حدوثه يمكن التنبؤ به إلى حد ما ، وبمجرد حدوث مثل هذه الحالة غير الطبيعية ، يجب التعامل معها بطريقة ما.
باستثناء RunTimeException ودراساته الفرعية ، فإن فئات الاستثناء الأخرى والفئات الفرعية كلها استثناءات قابلة للتحقق. تتمثل خاصية هذا الاستثناء في أن برنامج التحويل البرمجي Java سيقوم بفحصه ، أي عندما يحدث هذا الاستثناء في البرنامج ، إما التقاطه ببيان المحاولة أو رميه بفقرة Throws ، وإلا فلن يمر التجميع.
استثناءات غير قابلة للتحقيق (استثناءات من أن المترجم لا يتطلب التخلص القسري): بما في ذلك استثناءات وقت التشغيل (RunTimeException ودراساته الفرعية) والأخطاء (خطأ).
استثناء ينقسم هذا الاستثناء إلى فئتين: استثناء وقت التشغيل والاستثناء غير المحدد (استثناء التجميع). يجب التعامل مع هذه الاستثناءات قدر الإمكان في البرنامج.
استثناءات وقت التشغيل: جميعها فئة RunTimeException واستثناءات الفئة الفرعية الخاصة بها ، مثل NullPointerException (استثناء مؤشر NULL) ، indexoutofboundsexception (استثناء خارج الحدود خارج الحدود) ، إلخ. هذه الاستثناءات ناتجة بشكل عام بسبب أخطاء منطق البرنامج ، ويجب أن تتجنب البرامج مثل هذه الاستثناءات قدر الإمكان من منظور منطقي.
خاصية استثناء وقت التشغيل هي أن برنامج التحويل البرمجي Java لن يتحقق منه. وهذا يعني أنه عندما يحدث هذا الاستثناء في البرنامج ، حتى لو لم يتم التقاطه ببيان المحاولة وطرده بند رميات ، سيتم تجميعه وتمريره.
استثناء غير محدد (استثناء التجميع): هو استثناء آخر غير RunTimeException ، وينتمي إلى فئة الاستثناء والفئات الفرعية من حيث النوع. من منظور بناء جملة البرنامج ، إنه استثناء يجب معالجته. إذا لم تتم معالجتها ، فلا يمكن تجميع البرنامج وإقراره. مثل IOException و SQLException ، وما إلى ذلك ، واستثناءات الاستثناء المعرفة من قبل المستخدم ، بشكل عام ، لا يتم فحص استثناءات التحقق المخصصة.
3. آلية التعامل مع الاستثناء
في تطبيقات Java ، فإن آلية معالجة الاستثناء هي: استثناءات رمي واستثناءات التقاط.
رمي استثناء: عندما يحدث خطأ في طريقة ما ويثير استثناء ، فإن الطريقة تنشئ كائن استثناء وتسليمه إلى نظام وقت التشغيل. يحتوي كائن الاستثناء على معلومات استثناء مثل نوع الاستثناء وحالة البرنامج عند حدوث الاستثناء. نظام وقت التشغيل مسؤول عن العثور على التعليمات البرمجية وتنفيذها للتعامل مع الاستثناءات.
استثناء الاستثناء: بعد أن ترمي الطريقة استثناء ، سيتم تحويل نظام وقت التشغيل إلى البحث عن معالج استثناء مناسب. معالج الاستثناء المحتمل هو مجموعة من الأساليب التي تبقى في مكدس المكالمات بدورها عند حدوث استثناء. عندما يكون نوع الاستثناء الذي يمكن لمعالج الاستثناء معالجته متسقًا مع نوع الاستثناء الذي ألقيته الطريقة ، فهو معالج استثناء مناسب. يبدأ نظام وقت التشغيل بالطريقة التي يحدث فيها استثناء ، ثم ينظر إلى الأساليب الموجودة في مكدس الاتصال بدوره حتى يجد طريقة تحتوي على معالج استثناء مناسب وتنفيذها. عندما يعبر نظام وقت التشغيل مكدس الاتصال ولا يجد معالج استثناء مناسب ، ينتهي نظام وقت التشغيل. في الوقت نفسه ، يعني إنهاء برنامج Java.
بالنسبة لاستثناءات وقت التشغيل أو الأخطاء أو الاستثناءات القابلة للاكتشاف ، تختلف طرق معالجة الاستثناءات التي تتطلبها تقنية Java.
نظرًا لاستثناءات وقت التشغيل غير القابلة للكشف ، من أجل تنفيذ التطبيق بشكل أكثر معقولًا وسهولة ، تنص Java على أنه سيتم إلقاء استثناءات وقت التشغيل تلقائيًا بواسطة نظام تشغيل Java ، مما يسمح للتطبيق بتجاهل استثناءات وقت التشغيل.
بالنسبة للأخطاء التي قد تحدث أثناء تشغيل الطريقة ، تسمح Java للطريقة بعدم إلقاء أي إعلان عندما لا يتم التقاط الطريقة. نظرًا لأن معظم استثناءات الخطأ هي حالات لا يمكن السماح بها أبدًا ، وهي أيضًا استثناءات من عدم التقاط التطبيقات المعقولة.
لجميع الاستثناءات القابلة للتحقق ، تنص Java على أنه يجب اكتشاف الطريقة ، أو إعلانها خارج طريقة الرمي. أي عندما تختار طريقة ما عدم التقاط استثناء يمكن التحقق منه ، يجب أن يعلن أنه سيتم طرح الاستثناء.
تتطلب الطريقة التي يمكن أن تلتقط استثناءات توفير نوع مقابل من معالج الاستثناء. قد يكون سبب الاستثناء الذي تم صيده هو استثناء يتم إثارته وإلقاؤه ببيانه الخاص ، أو استثناء يتم إلقاؤه بواسطة طريقة تسمى أو نظام وقت تشغيل Java ، وما إلى ذلك. وبعبارة أخرى ، يجب أن يكون الاستثناء الذي يمكن أن يكون الاستثناء استثناءً من رمز Java في مكان ما. ببساطة ، يتم طرح الاستثناءات دائمًا أولاً ثم يتم القبض عليها.
يمكن لأي رمز Java إلقاء استثناءات ، مثل: الكود الذي كتبه بنفسك ، رمز من حزمة بيئة تطوير Java ، أو نظام Runtime Java. بغض النظر عن من هو ، يمكنك رمي استثناء من خلال بيان رمي جافا.
يجب استخدام أي استثناء تم إلقاؤه من الطريقة مع جملة TROWWS.
يتم تحقيق استثناءات التقاط من خلال عبارات المحاولة أو عبارات المحاولة.
بشكل عام ، تنص Java على أنه يجب اكتشاف استثناءات قابلة للتحقق أو إلقاءها. يسمح بتجاهل RunTimeException دون تحديد.
3.1 استثناءات التقاط: حاول ، اصطياد وأخيراً
1. بيان التمسك
في Java ، يتم اكتشاف الاستثناءات من خلال بيان التجربة. شكل بناء الجملة العام هو:
جرب {// رمز البرنامج حيث قد تحدث الاستثناءات} catch (type1 id1) {// catch والتعامل مع نوع الاستثناء الذي تم إلقاؤه بواسطة Try Type1} catch (type2 id2) {// catch and eled with type type type by try type2}زوج من الأقواس بعد الكلمة الرئيسية ، جرب يلف قطعة من التعليمات البرمجية التي قد يكون لها استثناء ، والذي يسمى منطقة المراقبة. في حالة حدوث استثناء أثناء طريقة Java أثناء التشغيل ، يتم إنشاء كائن استثناء. رمي الاستثناء خارج منطقة المراقبة ، ويحاول نظام وقت تشغيل Java العثور على جملة مطابقة للقبض على الاستثناء. إذا كان هناك شرط مطابقة ، فقم بتشغيل رمز معالجة الاستثناءات وينتهي عبارة المحاولة.
مبدأ المطابقة هو: إذا كان كائن الاستثناء الذي تم إلقاؤه ينتمي إلى فئة الاستثناء من جملة Catch أو ينتمي إلى فئة فرعية من فئة الاستثناء ، فسيُعتبر أن كائن الاستثناء الذي تم إنشاؤه يتطابق مع نوع الاستثناء الذي تم صيده بواسطة كتلة الصيد.
مثال 1 قبض على استثناء "Dividter IS 0" الذي تم إلقاؤه بواسطة بيان الرمي.
الفئة العامة testexception {public static void main (string [] args) {int a = 6 ؛ int b = 0 ؛ جرب {// جرب منطقة المراقبة إذا (b == 0) رمي ArithMeticexception () ؛ // استثناء رمي من خلال نظام الرمي. out.println ("قيمة A/ B هي:" + a/ b) ؛ } catch (ArithMeticexception e) {// catch catch stisply system.out.println ("البرنامج له استثناء ، ولا يمكن أن يكون المتغير B 0.") ؛ } system.out.println ("ينتهي البرنامج بشكل طبيعي.") ؛ }}نتيجة التشغيل: يحتوي البرنامج على استثناء ولا يمكن أن يكون المتغير B 0.
ينتهي البرنامج بشكل طبيعي.
مثال 1 في منطقة مراقبة المحاولة ، استخدم بيانًا للحكم. عندما يتم إنشاء حالة الخطأ لـ "Divider 0" ، يتم إنشاء استثناء ArithMeticeSception ، ويرمي بيان الرمي الاستثناء لنظام وقت تشغيل Java. يجد النظام صيد معالج استثناء مطابق ويقوم بتشغيل رمز معالجة الاستثناء المقابل. اطبع "البرنامج له استثناء ، ولا يمكن أن يكون المتغير B 0." ينتهي بيان المحاولة ويستمر في تدفق البرنامج.
في الواقع ، ArithMeticeSception مثل "Divider IS 0" هو فئة فرعية من RunTimexception. سيتم إلقاء استثناء وقت التشغيل تلقائيًا بواسطة نظام وقت التشغيل ، وليس هناك حاجة لاستخدام عبارة رمي.
مثال 2: استثناء استثناء ArithMeticexception الناجم عن "المقسم هو 0" تلقائيًا أثناء نظام وقت التشغيل.
public static void main (string [] args) {int a = 6 ؛ int b = 0 ؛ حاول {system.out.println ("قيمة a / b هي:" + a / b) ؛ } catch (ArithMeticexception e) {system.out.println ("البرنامج له استثناء ، والمتغير B لا يمكن أن يكون 0.") ؛ } system.out.println ("ينتهي البرنامج بشكل طبيعي.") ؛ }}نتيجة التشغيل: يحتوي البرنامج على استثناء ولا يمكن أن يكون المتغير B 0.
ينتهي البرنامج بشكل طبيعي.
بيان في المثال 2:
System.out.println ("قيمة A/B هي:" + A/B) ؛تم إنشاء خطأ في "Divider IS 0" أثناء وقت التشغيل ، وتم رفع استثناء ArithMeticeSception. يقوم نظام وقت التشغيل بإنشاء كائن استثناء ويرمي منطقة مراقبة ، بدلاً من ذلك يطابق صيد معالج الاستثناء المناسب ، ويقوم بتنفيذ رمز معالجة الاستثناء المقابل.
نظرًا لأن تكلفة التحقق من استثناءات وقت التشغيل أكبر بكثير من فوائد التقاط استثناءات ، لا يمكن اكتشاف استثناءات وقت التشغيل. يسمح برنامج التحويل البرمجي Java بتجاهل استثناءات وقت التشغيل ، ولا يمكن للطريقة التي لا يمكنها التقاط استثناءات أو إلقاء استثناءات وقت التشغيل.
مثال 3: لا يوجد صيد أو يعلن أنه يتم إلقاء استثناء وقت التشغيل.
الفئة العامة testexception {public static void main (string [] args) {int a ، b ؛ أ = 6 ؛ ب = 0 ؛ // قيمة المقسوم B هي 0 system.out.println (a / b) ؛ }}نتائج التشغيل:
استثناء في الموضوع "الرئيسي" java.lang.arithmeticexception: / by Zero
في Test.TestException.main (testexception.java:8)
مثال 4 قد يكون للبرنامج استثناء من المقسوم 0 واستثناء من المصفاة خارج الحدود.
الفئة العامة testexception {public static void main (string [] args) {int [] Intarray = new int [3] ؛ حاول {for (int i = 0 ؛ i <= intarray.length ؛ i ++) {intarray [i] = i ؛ System.out.println ("Intarray [" + i + "] =" + Intarray [i]) ؛ System.out.println ("Intarray [" + i + "] الوحدة النمطية" + (i - 2) + "القيم:" + Intarray [i] ٪ (i - 2)) ؛ }} catch (ArrayIndExOutofBoundSexception e) {system.out.println ("استثناء من intarray array خارج الحدود.") ؛ } catch (ArithMeticexception e) {system.out.println ("استثناء القسمة 0.") ؛ } system.out.println ("ينتهي البرنامج بشكل طبيعي.") ؛ }}نتائج التشغيل:
Intarray [0] = 0
Intarray [0] Value-2 Value: 0
Intarray [1] = 1
قيمة Intarray [1] Modulo-1: 0
Intarray [2] = 2
استثناء المقسوم 0.
ينتهي البرنامج بشكل طبيعي.
مثال 5 قد يواجه البرنامج استثناء من المقسوم 0 ، وقد يحدث استثناء من مشتركات الصفيف أيضًا. أثناء تشغيل البرنامج ، يتطابق نوع استثناء ArithMeticexception أولاً ، بحيث يتم تنفيذ بيان الصيد المطابق:
catch (ArithMeticexception e) {system.out.println ("استثناء المقسوم 0.") ؛ }تجدر الإشارة إلى أنه بمجرد التقاط المصيد يلتقط نوع الاستثناء المطابق ، فإنه سيدخل رمز معالجة الاستثناء. بمجرد الانتهاء من المعالجة ، فهذا يعني أن بيان المحاولة بأكمله ينتهي. لم تعد بنود الصيد الأخرى لديها فرصة لمطابقة أنواع الاستثناءات.
يصف Java أنواع الاستثناءات من خلال فئات الاستثناء ، ويظهر التسلسل الهرمي لفئات الاستثناء في الشكل 1. بالنسبة لبرامج الاستثناءات ذات الجمل المتعددة ، يجب أن تحاول وضع شرط الصيد الذي يلتقط فئة الاستثناء الأساسية أولاً ، ومحاولة وضع جملة الصيد التي تلتقط فئة الاستثناء ذات المستوى العالي نسبيًا لاحقًا. خلاف ذلك ، من المحتمل أن يتم حظر شرط الصيد الذي يمسك بفئة الاستثناء الأساسية.
تتضمن فئة استثناء RunTimeException استثناءات شائعة مختلفة في وقت التشغيل ، وفئة ArithMeticeSception وفئة ArrayIndExOutofBoundSexception كلاهما فئات فرعية. لذلك ، يجب وضع شرط catch لفئة استثناء RunTimeException في النهاية ، وإلا فإنه قد يحظر معالجة الاستثناء اللاحقة أو التسبب في خطأ في التجميع.
2. Try-Catch-Finally بيان
يمكن أن يتضمن بيان المحاولة أيضًا الجزء الثالث ، وهو البند الأخير. إنه يشير إلى ما يجب تنفيذه بغض النظر عما إذا كان الاستثناء يحدث أم لا. شكل بناء الجملة العام لبيان المحاولة-فونالي هو:
حاول {// رمز البرنامج الذي قد يحدث استثناء} catch (type1 id1) {// catch ومعالجة نوع الاستثناء الذي تم إلقاؤه بواسطة Try Type1} catch (type2 id2) {// catch ومعالجة نوع الاستثناء الذي تم إلقاؤه بواسطة Try Type2} أخيرًا {// كتلة من البيانات التي سيتم تنفيذها بغض النظر عما إذا كان هناك استثناء}}مثال 6 معالج الاستثناء مع شرط أخيرًا.
الفئة العامة TestException {public static void main (string args []) {int i = 0 ؛ تحيات سلسلة [] = {"Hello World!" ، "Hello World !!" ، "Hello World !!!" } ؛ بينما (i <4) {try {// انتبه بشكل خاص لتصميم متغير التحكم في الحلقة I لتجنب التسبب في حلقات لا حصر لها system.out.println (تحياتي [i ++]) ؛ } catch (ArrayIndExOutofBoundSexception e) {system.out.println ("استثناء من الحدود الخارجية") ؛ } أخيرًا {system.out.println ("--------------------------") ؛ }}}}نتائج التشغيل:
مرحبا بالعالم!
----------------------------------
مرحبا بالعالم !!
----------------------------------
مرحبا بالعالم!!!
----------------------------------
مجموعة مجموعة من الحدود استثناء
----------------------------------
في المثال 6 ، يرجى إيلاء اهتمام خاص لتصميم كتلة البيان في جملة Try. إذا كان التصميم كما يلي ، ستحدث حلقة ميتة. إذا تم تصميمه على النحو التالي:
حاول {system.out.println (تحية [i]) ؛ i ++ ؛ }ملخص:
جرب كتلة: تستخدم للقبض على الاستثناءات. بعد ذلك ، يمكن توصيل كتل الصيد أو أكثر. إذا لم يكن هناك كتلة صيد ، فيجب أن يتبعها كتلة أخيرًا.
Catch Block: يستخدم للتعامل مع الاستثناءات التي تم صيدها بواسطة المحاولة.
أخيرًا ، سيتم تنفيذ البيانات في الكتلة أخيرًا بغض النظر عما إذا كان الاستثناء قد تم اكتشافه أو معالجته. عند مواجهة بيان الإرجاع في كتلة المحاولة أو كتلة الصيد ، ستعمل كتلة البيان أخيرًا
ينفذ قبل إرجاع الطريقة. في الحالات الأربع التالية التالية ، لن يتم تنفيذ الكتلة أخيرًا:
1) حدث استثناء في كتلة البيان أخيرًا.
2) استخدم system.exit () في الكود السابق للخروج من البرنامج.
3) الخيط الذي يوجد فيه البرنامج يموت.
4) إيقاف تشغيل وحدة المعالجة المركزية.
3. القاعدة المحاولة-فونالي (القاعدة النحوية لبيان معالجة الاستثناء):
1) يجب إضافة مصيد أو كتلة أخيرًا بعد المحاولة. بعد كتلة المحاولة ، يمكن توصيل المصيد وأخيراً الكتل في نفس الوقت ، ولكن هناك كتلة واحدة على الأقل.
2) يجب اتباع ترتيب الكتلة: إذا كان الكود يستخدم كلا الصيد وأخيراً كتل ، فيجب وضع كتلة الصيد بعد كتلة المحاولة.
3) ترتبط كتلة الصيد بنوع فئة الاستثناء المقابلة.
4) قد تحتوي كتلة المحاولة على كتل متعددة. إذا كان الأمر كذلك ، يتم تنفيذ أول كتلة مطابقة. وهذا يعني أن جهاز Java Virtual يطابق كائنات الاستثناء الفعلية التي تم إلقاؤها مع أنواع الاستثناءات المعلنة بواسطة كل كتلة رمز الصيد بالتسلسل. إذا كان كائن الاستثناء هو نوع استثناء أو مثيل للفئة الفرعية الخاصة به ، فسيتم تنفيذ كتلة رمز الصيد ولن يتم تنفيذ كتلة رمز الصيد الأخرى.
5) هيكل المحاولة المتداخلة.
6) في بنية المحاولة--يمكن إعادة تربية استثناء.
7) بالإضافة إلى المواقف التالية ، ينتهي تنفيذ أخيرًا: ينتهي JVM قبل الأوان (يسمى System.exit (int)) ؛ يلقي استثناء غير معلم في الكتلة أخيرًا ؛ يتم تشغيل الكمبيوتر أو إطلاق النار أو الهجوم من قبل فيروس.
4. ترتيب تنفيذ المحاولة ، والقبض ، وأخيراً كتل العبارات:
1) عندما لا تُستقبل المحاولة استثناءً: يتم تنفيذ البيانات الواردة في كتلة TRAW BLOCK واحدة تلو الأخرى ، وسيقوم البرنامج بتخطي كتلة بيان الصيد وتنفيذ كتلة البيان أخيرًا والبيانات اللاحقة ؛
2) عندما تجذب المحاولة استثناء ، لا تتعامل كتلة بيان Catch مع هذا الاستثناء: عندما يحدث استثناء في بيان في كتلة TRAW TRAW ، وستظل كتلة بيان catch التي لا تتعامل مع هذا الاستثناء ، وسيتم إلقاء الاستثناء على JVM للمعالجة ، وسيظل البيان في كتلة البيان أخيرًا يتم تنفيذه ، ولكن لا يتم تنفيذ البيان بعد تنفيذ كتلة البيان أخيرًا ؛
3) عندما تجرب الاستثناء ، ستعالج كتلة بيان Catch هذا الاستثناء: يتم تنفيذها في كتلة عبارة TRY بالترتيب. عندما يحدث استثناء عند حدوث استثناء في بيان معين ، سيقفز البرنامج إلى كتلة بيان الصيد ويتطابق معها واحدًا تلو الآخر. العثور على المعالج المقابل. لن يتم تنفيذ كتل بيان الصيد الأخرى. في كتلة بيان المحاولة ، لن يتم تنفيذ البيان بعد استثناء. بعد تنفيذ كتلة بيان الصيد ، سيتم تنفيذ البيان في كتلة البيان أخيرًا ، وأخيراً سيتم تنفيذ البيان بعد تنفيذ كتلة البيان أخيرًا ؛
توضيح تنفيذ Try ، Catch ، وأخيراً كتل العبارات:
يوضح الشكل 2 تنفيذ Try ، Catch ، وأخيراً كتل العبارات
3.2 رمي استثناء
يمكن لأي رمز Java إلقاء استثناءات ، مثل: الكود الذي كتبه بنفسك ، رمز من حزمة بيئة تطوير Java ، أو نظام Runtime Java. بغض النظر عن من هو ، يمكنك رمي استثناء من خلال بيان رمي جافا. يجب استخدام أي استثناء تم إلقاؤه من الطريقة مع جملة TROWWS.
1. رمي رمي الاستثناء
إذا كانت الطريقة قد يكون لها استثناء ولكن ليس لديها القدرة على التعامل مع مثل هذا الاستثناء ، فيمكنك استخدام جملة THROWS لإعلان الاستثناء الذي تم إلقاؤه في إعلان الطريقة. على سبيل المثال ، قد تفشل السيارة عند الجري ، ولا يمكن للسيارة نفسها التعامل مع هذا الفشل ، لذلك دع السائق يتعامل معه.
يتم استخدام بيان الرميات لإعلان نوع الاستثناء الذي يجب رميه عند تحديد الطريقة. إذا تم إلقاء نوع الاستثناء ، يتم الإعلان عن الطريقة التي تطرح جميع الاستثناءات. يمكن تقسيم استثناءات متعددة باستخدام الفواصل. تنسيق بناء الجملة لبيان الرمي هو:
MethodName رمي الاستثناء 1 ، الاستثناء 2 ، .. ، استثناء {} رمي بعد اسم الطريقة الاستثناء 1 ، الاستثناء 2 ، ... ، الاستثناء هو قائمة الاستثناءات التي يجب إلقاؤها. عندما ترمي الطريقة قائمة استثناءات من الاستثناءات ، لن تتعامل الطريقة مع استثناءات من هذه الأنواع وأنواع الفئات الفرعية الخاصة بها ، ولكن سيتم إلقاؤها على الطريقة التي تستدعي الطريقة وسيتم معالجتها بها. على سبيل المثال:
استيراد java.lang.exception ؛ الطبقة العامة testexception {static void pop () يلقي negativearraysizeexception {// تحديد الطريقة ورمي استثناء negativearrayseixception int [] arr = new int [-3] ؛ // إنشاء صفيف} الفراغ الثابت العام (سلسلة [] args) {// الطريقة الرئيسية Try {// try state stateles معلومات الاستثناء pop () ؛ // استدعاء pop () method} catch (negativearraysizeexception e) {system.out.println ("استثناء تم إلقاؤه بواسطة طريقة pop ()") ؛ // معلومات استثناء الإخراج}}}بعد إلقاء الاستثناء على المتصل باستخدام الكلمة الرئيسية رميات ، إذا كان المتصل لا يريد التعامل مع الاستثناء ، فيمكنك الاستمرار في رميه ، ولكن في النهاية يجب أن يكون هناك متصل يمكنه التعامل مع الاستثناء.
لا تتعامل طريقة POP مع الاستثناء NegatiVearraysizeException ، ولكن يتم التعامل معها بواسطة الوظيفة الرئيسية.
قاعدة رميات لرمي الاستثناءات:
1) إذا كان ذلك استثناءً غير مرغوب فيه ، أي خطأ ، أو RunTimeException أو فئاتها الفرعية ، فيمكنك إعلان الاستثناء الذي يتم إلقاؤه دون استخدام الكلمة الرئيسية رميات ، وسيظل المجموعة يمر بسلاسة ، ولكن سيتم إلقاؤه بواسطة النظام في وقت التشغيل.
2) يجب الإعلان عن أي استثناءات محددة يمكن إلقاؤها بواسطة الطريقة. أي أنه إذا كان لدى الطريقة استثناء يمكن فحصه ، فسيتم إما أن يتم اكتشافه ببيان محاولة أو رميه بإعلان جملة رمي ، وإلا فإنه سيؤدي إلى خطأ في الترجمة.
3) فقط عند إلقاء استثناء ، يجب أن يتعامل المتصل للطريقة أو إعادة تقديمه إلى الاستثناء. عندما يكون المتصل الطريقة غير قادر على التعامل مع الاستثناء ، يجب أن يستمر في رميه بدلاً من ابتلاعه بالكامل.
4) يجب أن تتبع طريقة الاتصال أي قواعد معالجة وإعلان استثناء. إذا تم الكتابة فوق الطريقة ، فلا يمكن الإعلان عن استثناءات مختلفة عن الطريقة المكتوبة. يجب أن يكون أي استثناء يُعلن أنه فئة مشابهة أو فرعية من الاستثناء المعلنة من خلال طريقة تجاوزها.
على سبيل المثال:
method method1 () يلقي ioException {} // legal // خطأ التجميع ، يجب أن يتم اكتشاف ioException أو إعلانه لرمي method2 () {method1 () ؛ }. }. } // Legal ، capture ioException void method5 () {try {method1 () ؛ } catch (IoException e) {...}} // خطأ في التجميع ، يجب عليك التقاط أو إعلان استثناء method6 () {try {method1 () ؛ } catch (ioException e) {رمي استثناء جديد () ؛}} // Legal ، DERNARE DREAN ASSERSS METRODE 7 () يلقي الاستثناء {try {method1 () ؛ } catch (ioException e) {رمي استثناء جديد () ؛}} أساس تحديد أن الاستثناء قد يحدث في طريقة ما يلي:
1) هناك بيان رمي في الطريقة. على سبيل المثال ، تحتوي كتلة رمز الصيد على طريقة Method7 () أعلاه على بيان رمي.
2) تسمى الطرق الأخرى ، والطرق الأخرى تستخدم جملة رميات لإعلان بعض الاستثناءات لرميها. على سبيل المثال ، تستدعي طريقة Method3 () طريقة Method1 () ، وتعلن الطريقة Method1 () أنه يتم إلقاء ioException ، لذلك قد يحدث iOexception في طريقة Method3 ().
2. استخدم رمي لرمي الاستثناء
يظهر رمي دائمًا في جسم الوظيفة ويستخدم لإلقاء استثناء من النوع القابل للرمي. سينتهي البرنامج مباشرة بعد بيان الرمي ، والبيان بعده لا يمكن تنفيذه ، ثم في جميع كتل المحاولة التي تحتوي عليها (ربما في وظيفة الاتصال على المستوى العلوي) ابحث عن كتل المحاولة التي تحتوي على شرط الصيد الذي يطابقها من الداخل إلى الخارج.
نحن نعلم أن الاستثناءات هي كائنات مثيل لفئة الاستثناء ، ويمكننا إنشاء كائنات مثيل لفئة الاستثناء ليتم إلقاؤها من خلال بيان الرمي. تنسيق بناء الجملة لهذا البيان هو:
رمي اسم استثناء جديد.
على سبيل المثال ، رمي كائن استثناء من فئة IOException:
رمي ioexception جديد.
تجدر الإشارة إلى أن يلقي فقط كائنات مثيلات يمكن أن ترمي فئات قابلة للرمي أو فئات فرعية. العملية التالية غير صحيحة:
رمي سلسلة جديدة ("استثناء") ؛هذا لأن السلسلة ليست فئة فرعية من فئة الرمي.
إذا تم طرح استثناء فحص ، فيجب عليك أيضًا إعلان نوع الاستثناء الذي قد يرميه الطريقة في رأس الطريقة. يجب على المتصل في هذه الطريقة أيضًا التحقق من التعامل مع الاستثناء الذي تم إلقاؤه.
إذا كانت جميع الأساليب ترمي طبقة الاستثناء المكتسبة حسب الطبقة ، فسيقوم JVM بمعالجةها في النهاية ، كما أن المعالجة بسيطة للغاية ، وهي طباعة معلومات الاستثناء والمعلومات. إذا تم طرح خطأ أو RunTimeException ، فإن المتصل بالطريقة لديه خيار التعامل مع الاستثناء.
اختبار الحزمة استيراد java.lang.exception ؛ يرمي الفئة العامة testexception {static int quient (int x ، int y) myException {// تحديد الطريقة لرمي استثناء إذا كان (y <0) {// تحديد ما إذا كانت المعلمة أقل من 0 رمي myException جديد ("لا يمكن أن يكون المقسوم رقمًا سالبًا") ؛ // معلومات استثناء} إرجاع x/y ؛ // قيمة الإرجاع} الفراغ الثابت العام (سلسلة args []) {// main method int a = 3 ؛ int b = 0 ؛ TREE {// TREE TRY يحتوي عبارة على عبارات قد يكون لها استثناءات int = quient (a ، b) ؛ // call method quoteent ()} catch (myException e) {// التعامل مع sustem.out.println (e.getMessage ()) ؛ // معلومات استثناء الإخراج} catch (ArithMeticexception e) {// التعامل مع ArithMeticexception Security System.out.println ("DivorceIpt لا يمكن أن يكون 0") ؛ // معلومات موجه الإخراج} catch (استثناء e) {// التعامل مع الاستثناءات الأخرى system.out.println ("حدثت استثناءات أخرى في البرنامج") ؛ // معلومات موجه الإخراج}}} الفئة myException تمتد استثناء {// إنشاء رسالة سلسلة فئة استثناء مخصص ؛ // تحديد نوع السلسلة المتغير العام myException (سلسلة errormessagr) {// رسالة الفئة الأصل = errormessagr ؛ } السلسلة العامة getMessage () {// override getMessage () طريقة إرجاع طريقة ؛ }}3.3 سلسلة الاستثناء
1) إذا تم استدعاء حاصل (3 ، -1) ، فسيحدث استثناء MyException وسيتم نقل البرنامج إلى كتلة رمز Catch (MyException E) للتنفيذ ؛
2) إذا تم استدعاء Quotient (5،0) ، فسيتم رفع استثناء ArithMeticeSception بسبب خطأ "المقسم هو 0". ينتمي إلى فئة استثناء وقت التشغيل ويتم إلقاؤه تلقائيًا بواسطة نظام وقت تشغيل Java. طريقة quitient () لا تصطاد استثناء ArithMeticeSception. سيبحث نظام وقت تشغيل Java عن الطريقة الرئيسية على طول مكدس استدعاء الطريقة وتحميل الاستثناء الذي تم إلقاؤه إلى المتصل بالطريقة Quitient ():
int النتيجة = حاصل (a ، b) ؛ // call method quient ()
نظرًا لأن هذا البيان موجود في منطقة مراقبة المحاولة ، يتم إلقاء ArithMeticeSception مع "Divider IS 0" تم تمريره بواسطة نظام وقت تشغيل Java ويتطابق مع جملة Catch:
catch (ArithMeticexception e) {// التعامل مع ArithMeticexception issupe.out.println ("لا يمكن أن يكون المقسوم 0") ؛ // معلومات موجه الإخراج}نتيجة المعالجة هي أن الإخراج "مقسم لا يمكن أن يكون 0". تشكل جافا ، وهي آلية معالجة تمرر معلومات الاستثناء إلى الأعلى ، سلسلة استثناء.
سيتم تمرير الاستثناء القابل للتحقق الذي تم إلقاؤه بواسطة طريقة Java إلى طريقة الاتصال مع إمكانية المعالجة بناءً على مكدس الاتصال وعلى طول التسلسل الهرمي لمكالمة الطريقة ، وسيكون أعلى مستوى حتى الطريقة الرئيسية. إذا تم نقل الاستثناء إلى الطريقة الرئيسية ، ولكن لا يتمتع الرئيسي بالقدرة على التعامل معها ولا يرمي الاستثناء من خلال إعلان الرميات ، فقد يحدث خطأ في التجميع.
3) في حالة حدوث استثناءات أخرى ، سيتم استخدام Catch (استثناء E) للقبض. Since Exception is the parent class of all exception classes, if the catch (Exception e) code block is placed in front of the other two code blocks, the subsequent code blocks will never be executed, which makes no sense, so the order of catch statements cannot be replaced.
3.4 Throwable类中的常用方法
注意:catch关键字后面括号中的Exception类型的参数e。Exception就是try代码块传递给catch代码块的变量类型,e就是变量名。catch代码块中语句"e.getMessage();"用于输出错误性质。通常异常处理常用3个函数来获取异常的有关信息:
getCause():返回抛出异常的原因。如果cause 不存在或未知,则返回null。
getMeage():返回异常的消息信息。
printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段System.err 的值。
有时为了简单会忽略掉catch语句后的代码,这样try-catch语句就成了一种摆设,一旦程序在运行过程中出现了异常,就会忽略处理异常,而错误发生的原因很难查找。
5.Java常见异常
在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。Java中常见的异常类:
1. runtimeException子类:
1、 java.lang.ArrayIndexOutOfBoundsException
数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
2、java.lang.ArithmeticException
算术条件异常。譬如:整数除零等。
3、java.lang.NullPointerException
空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等
4、java.lang.ClassNotFoundException
找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
5、java.lang.NegativeArraySizeException 数组长度为负异常
6、java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常
7、java.lang.SecurityException 安全性异常
8、java.lang.IllegalArgumentException 非法参数异常
2.IOException
IOException:操作输入流和输出流时可能出现的异常。
EOFException 文件已结束异常
FileNotFoundException 文件未找到异常
3. 其他
ClassCastException 类型转换异常类
ArrayStoreException 数组中包含不兼容的值抛出的异常
SQLException 操作数据库异常类
NoSuchFieldException 字段未找到异常
NoSuchMethodException 方法未找到抛出的异常
NumberFormatException 字符串转换为数字抛出的异常
StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
IllegalAccessException 不允许访问某类异常
InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常
6.自定义异常
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
在程序中使用自定义异常类,大体可分为以下几个步骤。
(1)创建自定义异常类。
(2)在方法中通过throw关键字抛出异常对象。
(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
(4)在出现异常方法的调用者中捕获并处理异常。
在上面的“使用throw抛出异常”例子已经提到了。
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.