شرح - try java




استثناء جافا لم يتم اكتشافه (5)

لماذا لا يتم اكتشاف بعض الاستثناءات في Java عن طريق catch (Exception ex) ؟ هذا الرمز يفشل تمامًا مع استثناء غير معالج. (إصدار Java 1.4).

public static void main(String[] args) {
    try {
        //Code ...
    } catch (Exception ex) {
        System.err.println("Caught Exception");
        ex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    }
    finally {
        app.shutdown();
    }
    System.exit(exitCode);
}

أحصل على Exception in thread "main" java.lang.NoSuchMethodError

لكن هذا يعمل

public static void main(String[] args) {
    int exitCode = app.SUCCESS_EXIT_CODE;
    try {
        //Code ...
    } catch (java.lang.NoSuchMethodError mex){
        System.err.println("Caught NoSuchMethodError");
        mex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    } catch (Exception ex) {
        System.err.println("Caught Exception");
        ex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    }
    finally {
        app.shutdown();
    }
    System.exit(exitCode);
}

لقد Caught NoSuchMethodError java.lang.NoSuchMethodError: على Caught NoSuchMethodError java.lang.NoSuchMethodError:

اعتقدت أن اصطياد الاستثناءات سيصطاد جميع الاستثناءات؟ كيف يمكنني التقاط جميع الاستثناءات في جافا؟


أولاً ، دعنا نقضي على بعض الالتباس الدلالي المؤسف في هذه المناقشة. هناك فئة java.lang.Exception التي يمكننا الإشارة إليها ببساطة باسم Exception برأس مال 'E'. ثم لديك استثناء مع صغيرة 'e' وهي ميزة اللغة. يمكنك مشاهدة إصدار Throwable في Throwable الفئة Throwable :

لأغراض التحقق من وقت الاستثناءات ، تعتبر Throwable وأي فئة فرعية من Throwable التي ليست أيضًا فئة فرعية من RuntimeException أو Error استثناءات محددة.

بالنسبة لي ، من الأسهل التفكير في إجابة هذا السؤال على أنه تم تحديده مقابل استثناءات غير محددة (الحالة الصغيرة e). يجب النظر في الاستثناءات المحددة في وقت الترجمة ، في حين أن الاستثناءات التي لم يتم التحقق منها ليست كذلك. يتم التحقق من استثناءات (الأحرف الكبيرة E) وفئاتها الفرعية استثناءات ، مما يعني أنه عليك إما الاستيلاء على أي استثناء يمكن إلقاؤه بواسطة التعليمات البرمجية الخاصة بك ، أو إعلان الاستثناءات التي قد تطرحها طريقتك (إذا لم يتم اكتشافها).

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

النظر في التعليمات البرمجية التالية:

void test() {
  int a = 1, b = 0, c = a / b;
}

عند التشغيل ، سوف ينتج عن الكود أعلاه java.lang.ArithmeticException . سيتم تجميع هذا دون أي أخطاء ، على الرغم من وجود استثناء والرمز لا يمسك ArithmeticException ولا يعلن أنه يلقي هذا الاستثناء. هذا هو جوهر الاستثناءات غير المحددة.

النظر في موقع ArithmeticException في التسلسل الهرمي للفئة ، وخاصة حقيقة أن هذه هي فئة فرعية من java.lang.Exception. يوجد لديك استثناء مستمد من java.lang.Exception ، ولكن نظرًا لأنه أيضًا صنف فرعي من java.lang.RuntimeException ، فهو استثناء لم يتم التحقق منه حتى لا تضطر إلى التقاطه.

java.lang.Object
  java.lang.Throwable
    java.lang.Exception
      java.lang.RuntimeException
        java.lang.ArithmeticException

إذا كنت تريد التقاط أي شيء يمكن إلقاؤه ، يمكنك التقاط ثغرة. ومع ذلك ، قد لا يكون هذا هو الشيء الأكثر أمانًا الذي يجب القيام به لأن بعض تلك Throwables يمكن أن تكون ظروفًا قاتلة لوقت التشغيل وربما لا ينبغي القبض عليها. أو إذا واجهت مشكلة Throwable ، فقد ترغب في إعادة رمي Throwables التي لا يمكنك التعامل معها. ذلك يعتمد على السياق.


الاستثناء هو مجرد نوع واحد من Throwable. NoSuchMethodError ليس استثناء ، ولكنه خطأ ، وهو نوع آخر من Throwable.


كما تشير كلتا الوظيفتين الأخريين ، لن يعمل catch (Exception e) إلا من أجل الاستثناءات المستمدة من Exception . ومع ذلك ، إذا نظرت إلى التسلسل الهرمي للشجرة ، ستلاحظ وجود استثناء إذا كان Throwable . Throwable هي أيضًا الفئة الأساسية لـ Error أيضًا. لذلك ، في حالة NoSuchMethodError ، إنه خطأ وليس استثناء. لاحظ اصطلاح التسمية * خطأ مقابل * استثناء (كما في IOException ، على سبيل المثال).


لأن بعض الاستثناءات لا تستمد من Exception - مثل Throwable and Error .

أساسا التسلسل الهرمي للنوع هو:

       Object
         |
      Throwable
     /         \
Exception      Error

يمكن Throwables فقط Throwables والفئات المشتقة ، لذلك إذا Throwable ، فهذا سيؤدي حقًا إلى التقاط كل شيء.

Throwable و Exception وأي استثناء مستمد من Exception بخلاف تلك المستمدة من RuntimeException استثناءات محددة - إنها الاستثناءات التي يتعين عليك التصريح Throwable أو Throwable إذا اتصلت بشيء يلقي بها.

أخبرنا أن التسلسل الهرمي باستثناء Java هو عبارة عن حالة من الفوضى ...


Error ليس Exception s.

استثناء الفئة والفئات الفرعية الخاصة به هي شكل من أشكال Throwable يشير إلى الشروط التي قد يرغب أحد التطبيقات المعقولة في التقاطها.

- Exception

خطأ هو فئة فرعية من Throwable تشير إلى مشاكل خطيرة يجب ألا يحاول تطبيق معقول التقاطها.

- Error

هناك بعض الأخطاء التي قد ترغب في التقاطها ، مثل ThreadDeath . يتم تصنيف ThreadDeath كخطأ ، كما هو موضح أدناه

فئة ThreadDeath هي فئة فرعية من Error بدلاً من Exception على وجه التحديد ، على الرغم من أنها "حدث عادي" ، لأن العديد من التطبيقات تلتقط كل تكرارات Exception ثم تتجاهل الاستثناء.

- ThreadDeath

ومع ذلك ، نظرًا لأن أسلوب الإيقاف () الخاص بسلسلة رسائل تم إهمالها الآن ، يجب ألا تستخدمها ، وبالتالي يجب ألا تشاهد ThreadDeath أبدًا.







try-catch