لماذا لا يتم القبض على nullpointerexception في كتلة الصيد الخاصة بي؟

StackOverflow https://stackoverflow.com/questions/776765

سؤال

لدي مؤشر ترابط أقوم به كل الأخطاء في كتلة الصيد الكبيرة والشاملة. أفعل هذا حتى أتمكن من الإبلاغ عن أي خطأ، وليس فقط من المتوقع، في طلبي. بلدي runnable يبدو وكأنه هذا:

public final void run()
{
    try
    {
        System.out.println("Do things"); /* [1] */

        doUnsafeThings();
    }
    catch (Throwable t)
    {
        System.out.println("Catch"); /* [2] */

        recover();
    }
    finally
    {
        System.out.println("Finally"); /* [3] */
    }
}

أتوقع أن يتم القبض على NPE من قبل كتلة الصيد القابلة للإزالة. بدلا من ذلك، لا يتم طباعة الإخراج في [2]، ولا يوجد [3]. يتم طباعة الإخراج في [1].

ما أفعله على وحدة التحكم، هل هذا:

Uncaught exception java/lang/NullPointerException.

هل ما يحدث هنا يجري على الأرض؟

بالنسبة لسجلات المحكمة، فأنا أستخدم J2ME، وهذا يعمل بمحاكي Sun's WTK V2.5.2.

أنا أتم إغراءه لوضعه إلى DODGiness لتنفيذ JVM لكنني لا أستطيع المساعدة في الشعور بأنني أفتقد شيئا فقط.

لتوضيح تجنب الشك (نظرا لأن رمز المثال يتم تغييره من الواضح من كود الإنتاج الخاص بي)

  • لا يوجد شيء خارج TRY / CATCK / أخيرا في طريقة التشغيل.
  • هناك system.out.println في بداية كل كتلة من تلك الكتل - ما يتبع بيانات وحدة التحكم هذه لا ينبغي أن لا يهم.
هل كانت مفيدة؟

المحلول

الجواب تبين أنني أحمق. أود أن أشرح ما حدث خطأ، لكن دعنا نسميها فقط "أحد هذه الأخطاء".

كنت قد نسيت لحظات أن الخيط الذي صادف Runnable كان فئة مؤشر ترابط مخصص (للحصول على جولة بعض البق نوكيا). ودعا run() مرارا وتكرارا بين المكالمات إلى canWait() طريقة.

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

نصائح أخرى

يبدو وكأنه ستحتاج إلى بعض التجربة والخطأ. هل لي أن أقترح:

try {
    doEvilStuff();
} catch (NullPointerException ex) { 
    System.out.println("NPE encountered in body"); 
} catch (Throwable ex) {
    System.out.println("Regular Throwable: " + ex.getMessage());
} finally {
    etc...
}

من خلال امتلاك صريحا ل NullPointerException، يجب أن يصبح واضحا إذا كان الاستثناء من داخل كتلة المحاولة أو كتلة الصيد / النهاية.

حسنا، هذا تخمين بري ... لكنه سيشرح الأشياء.

من الواضح رمزك ليس فعلا ذلك - لذلك تخميني هو أن كتلة الصيد (أو أخيرا) إما القيام بشيء ما قبل أن يسجل أي شيء، أو يستخدم مسجل مختلف عن كتلة المحاولة. في كلتا الحالتين، أظن أن الصيد أو كتلة أخيرا هو رمي الاستثناء.

لا أفترض أن لديك تتبع مكدس ...

تحرير: حسنا، إذا كان فقط System.out.println, ، هل هو شيء في الحجة التي قد تذهب بانج؟ علي سبيل المثال:

catch (Throwable t) {
    // Will go bang if t.getCause() returns null
    System.out.println(t.getCause().getMessage());
}

إذا كان مجرد بسيطة System.out.println("Constant") ثم انها غريبة جدا.

هل تعرف (على سبيل المثال من خطوط السجل داخل كتلة المحاولة) إلى أي مدى يحصل كتلة المحاولة بالفعل؟

عندما نظرت إلى التعليمات البرمجية، يبدو أن التعافي () يرمي استثناء، وبالتالي فإن النصيحة المقدمة من جون ستكون ممتازة لمتابعة.

إذا قدمت لنا تتبع مكدس قد تحصل على مساعدة أفضل.

عندما أحاول أن أسكون باستثناءات أفعل شيئا مثل هذا:

try {
  doSomethingBad();
} catch(Exception e) {
   try {
      LogException(...);
   } catch(Exception e) {}       
} finally {
}

أنا لا أحب أن عش الاستثناءات، لكنني لا أحب استثناءات إلقاء كتلة الصيد الخاصة بي.

كما ذكرك أنت تستخدم Runnable - هل هذا من خلال أي فرصة يعني أنك تستخدم مؤشرات الترابط متعددة كذلك؟ إذا كان doUnsafeThings() طريقة تطرد داخليا مؤشر ترابط مختلف مرة أخرى وهذا ينتج الاستثناء، قد لا تحصل عليه في مؤشر الترابط الخاص بك. يرى http://java.sun.com/j2se/1.5.0/docs/api/java/lang/thread.uncousexceptionhandler.html.

من الممارسة السيئة بشكل عام للقبض على nullpointerexception.

عادة ما يمسك مبرمجون NullPointerException تحت ثلاث ظروف:

The program contains a null pointer dereference. Catching the resulting exception was easier than fixing the underlying problem.
The program explicitly throws a NullPointerException to signal an error condition.
The code is part of a test harness that supplies unexpected input to the classes under test. 

من هذه الظروف الثلاث، فقط آخر مقبول. بعد هذا الرابط:

قبض على nullpointerException.

هل من الممكن أن يقتل الخيط من قبل بعض الكود الآخر؟ بشكل عام، تم تنفيذ كتلة أخيرا دائما ما لم يتم إنهاء الخيط بشكل غير طبيعي، إما عن طريق System.exit () أو شيء مشابه.

  • هل أنت متأكد أنك تبحث في المكان المناسب في الكود؟ IE، هل كتلة dounsafethings () تحمي في تتبع المكدس؟

  • ربما هناك مشكلة في طريقة البناء الخاصة بك، وأنت تصحيح نسخة قديمة من التعليمات البرمجية؟

فقط أضف بعض التسجيل في Dounsafeethings ()؛ لمعرفة ما إذا كانت هذه الطريقة تفعل ما تتوقعه (على سبيل المثال، ضع قبض أخيرا وتسجيل شيء ما)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top