سؤال

لقد تساءلت دائما لماذا لا يخبرك JVM أيّ مؤشر (أو أكثر بدقة، أي متغير) فارغ عندما NullPointerException هذا خطئ.

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

هل هناك أي علم مترجم أو علامة JVM التي من شأنها أن تجعل رسائل الاستثناء هذه مفيدة للغاية؟

هل كانت مفيدة؟

المحلول

ذلك لأن الديريل يحدث دائما عندما لا يكون هناك اسم متاح. يتم تحميل القيمة على كومة المعامل، ثم يتم تمريرها بعد ذلك إلى واحدة من jre opcodes التي تقوم بإجراء dereference عليه. ومع ذلك، فإن كومة المعامل لا تحتوي على اسم للربط بقيمة فارغة. كل ما لديه هو "null". مع بعض رمز تتبع وقت التشغيل الذكي، يمكن اشتقاق الاسم، ولكن هذا من شأنه أن يضيف النفقات العامة ذات قيمة محدودة.

لهذا السبب، لا يوجد خيار JRE الذي سيقوم بتشغيل معلومات إضافية لاستثناءات مؤشر NULL.

في هذا المثال، يتم تخزين المرجع في الفتحة المحلية 1، والذي يقوم بالخرائط إلى اسم متغير محلي. لكن الديريل يحدث في التعليمات InvokeVirtual، والتي ترى فقط قيمة "NULL" على المكدس، ثم يلقي استثناء:

15 aload_1
16 invokevirtual #5 

سيكون صالحا بنفس القدر سيكون عبء صفيف متبوعا ب Deereference، ولكن في هذه الحالة لا يوجد اسم للخريطة إلى القيمة "NULL"، مجرد فهرس خارج قيمة أخرى.

76 aload    5
78 iconst_0
79 aaload
80 invokevirtual #5

لا يمكنك تخصيص الأسماء القانونية لكل تعليمات إما - هذا المثال ينتج الكثير من Pytecode، ولكن يمكنك أن ترى أن تعليمات Dereference ستتلقى إما OBJA أو OBJB، وستحتاج إلى تتبع هذا ديناميكيا للإبلاغ عن اليمين كما يتدفق كلا المتغيرين إلى نفس تعليمات dereference:

(myflag ? objA : objB).toString()

نصائح أخرى

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

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

لو

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

ثم أقترح:

  1. كسر هذا الخط إلى أكثر من سطر واحد وتعيين ممكن NullPointerException- القيم المتجهة إلى المتغيرات المؤقتة.
  2. استخدم مصححا وتدخل كل طريقة مكالمة حتى تجد الشخص الذي يسبب المشكلة.

هذا لسوء الحظ، فقط Way Java يعمل.

إذا كان هذا هو رمز "الخاص بك"، فما عليك سوى إضافة مقتطفات

if (foo == null) {
  throw new NullPointerException("foo == null");
}

مباشرة بعد تعيين فو. إذا كانت Foo هي معلمة، فقم بفحصها على الفور في بداية هيئة الطريقة، ورميها بشكل غير طبيعي.

هذا ينبغي أن يساعدك في توضيح الأمور.

يمكنك إضافة نقطة توقف في استثناء مؤشر NULL في الكسوف عند تصحيح الأخطاء للحصول على السبب الدقيق للاستثناء.

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