English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
قال لي المدرس، أن معظم الاستثناءات في المستقبل ستكون استثناءات نصوص فارغة. لذا، حاول أن تأخذ بعض الوقت للعب الألعاب لمعرفة ما هو استثناء النص الفارغ
أولاً، الأسباب الرئيسية لحدوث استثناء النص الفارغ هي:
(1) عند إجراء دعوة إلى طريقة كائن غير موجود سيتم إنتاج استثناء obj.method() // لا يوجد كائن obj
(2) عند الوصول إلى أو تعديل حقل غير موجود في الكائن سيتم إنتاج استثناء obj.method() // لا يوجد عمود method
(3) لم يتم تخصيص متغير النص;
(4) لم يتم تخصيص كائن من نوع واجهة باستخدام فئة محددة، مثل:
List lt؛ سيحدث خطأ
List lt = new ArrayList(); لن يحدث خطأ
عندما يكون قيمة الكائن فارغة، لم تقم بتحديد أن القيمة فارغة. يمكنك تجربة إضافة سطر من هذا القبيل قبل الكود التالي:
إذا (rb != null && rb !== "")
أصبح:
إذا (rb == null); إذا (rb !== null && rb !== "") أو إذا (("").equals(rb))
حلول استثناء النص الفارغ:
ركز على السطر الذي حدث فيه الخطأ، وحدد الخطأ الدقيق من خلال أسباب اثنين رئيسية لحدوث استثناء النص الفارغ. بالإضافة إلى ذلك، من أجل تجنب حدوث استثناء النص الفارغ، من الأفضل وضع 'null' أو القيمة الفارغة قبل القيمة المحددة عند القيام بالتحقق من الصحة.
تحليل مختصر لأكثر استثناءات النصوص الفارغة شيوعًا:
(1) خطأ ناقص النص Java.lang.NullPointerException
توجد 8 أنواع بسيطة من البيانات في Java، يمكن أن يكون للمتغيرات قيم افتراضية، إذا لم يتم تخصيصها بشكل صحيح، فإن محرك Java الافتراضي لا يمكنه التجميع بشكل صحيح، لذلك لا يسبب استخدام الأنواع الأساسية في Java استثناءات ناقص النص.
ثانيًا، ميكانيكية معالجة الاستثناءات في Java
هناك طريقتان لمعالجة الكود الذي قد يسبب استثناءات:
الأول، استخدم جملة try...catch لالتقاط وتعامل مع الاستثناءات، يمكن أن تكون هناك عدة جمل catch لتطابق استثناءات متعددة. على سبيل المثال:
public void p(int x){ try{ ... }catch(Exception e){ ... }finally{ ... }}
ثانياً، للتعامل مع الاستثنائية التي لا يمكن معالجتها أو الاستثنائية التي يجب تحويلها، يجب استخدام
استخدام جملة throws لرفع الاستثنائية. على سبيل المثال:
public void test1() throws MyException{ ... if(....){ throw new MyException(); }}
إذا كانت كل طريقة كانت ترفع استثنائية ببساطة، فإن الجهاز الافتراضي لبرنامج Java سيبحث في مكتبة التطبيق من الكود الذي حدث فيه الاستثنائية إلى الأسفل حتى يجد الكود الذي يمكن معالجة الاستثنائية. ثم يتم تسليم الاستثنائية إلى جملة الاستثنائية المماثلة. إذا لم يجد الجهاز الافتراضي لبرنامج Java مكتبة معالجة الاستثنائية عند الوصول إلى أسفل مكتبة التطبيق، فإنه يتم التعامل معه بناءً على الخطوات التالية:
أولاً، يجب على المستخدمين طباعة معلومات الاستثنائية لمكتبة الاستثنائية باستخدام طريقة printStackTrace().
ثانياً إذا كان السطر الذي حدث فيه الاستثنائية هو السطر الرئيسي، فإن تشغيل البرنامج كله يتوقف; إذا كان غير السطر الرئيسي، يتم إنهاء هذا السطر، والسطور الأخرى تستمر في التشغيل.
من خلال التحليل والتفكير، يمكن ملاحظة أن معالجة الاستثنائية في وقت مبكر تستهلك موارد أقل وتستهلك وقت أقل، وتقلل من نطاق التأثير. لذلك، لا يجب أن يتم رفع الاستثنائية التي يمكن معالجتها نفسها إلى المُستدعي.
شيء آخر يجب عدم نسيانه: يجب تنفيذ جملة في النهاية في جميع الحالات، مما يضمن ثقة الأوامر التي يجب تنفيذها في جميع الحالات. على سبيل المثال، عند حدوث استثنائية في استعلام قاعدة البيانات، يجب إطلاق الاتصال JDBC. جملة في النهاية تنفذ قبل جملة العودة، بغض النظر عن الترتيب، أو ما إذا كان هناك استثنائية في مكتبة تحاول. الوحيد الذي لا تنفذ فيه جملة في النهاية هو عند تنفيذ System.exit()، الذي يوقف الجهاز الافتراضي لبرنامج Java. لا يمكن تغيير قيمة العودة من خلال تعيين قيمة جديدة للمعلمة في جملة في النهاية، ويُنصح بعدم استخدام جملة العودة في جملة في النهاية، لأن ذلك ليس له معنى ويمكن أن يؤدي إلى أخطاء.
أيضاً يجب الانتباه إلى قواعد синтaxis لمعالجة الاستثنائية:
أولاً、جملة تحاول لا يمكن أن تكون موجودة بشكل منفرد، يمكن أن تكون مع جملة الاستثنائية، جملة في النهاية.
تحاول...استثنائية...في النهاية، تحاول...استثنائية، تحاول...في النهاية ثلاثة بنيات، جملة الاستثنائية يمكن أن تكون واحدة أو أكثر، جملة في النهاية يمكن أن تكون واحدة فقط، الكلمات المفتاحية تحاول، الاستثنائية، في النهاية لا يمكن استخدامها بشكل منفرد.
ثانيًا:تكون مجالات التأثير لـ blocks try، catch، و finally مستقلة عن بعضها البعض ولا يمكنها الوصول إلى بعضها البعض. إذا كنت بحاجة إلى الوصول إلى المتغيرات في هذه blocks الثلاثة، يجب عليك تعريف المتغيرات خارج هذه blocks.
ثالثًا:عند وجود عدة blocks catch، يقوم Java Virtual Machine بمطابقة واحدة من أنواع الاستثناءات أو فرعها، ويُ�行ر على هذا block، ولا يُستمر في تنفيذ أي block آخر.
رابعًا:لا يُسمح بوجود جملة أخرى تتبع جملة throw، لأن هذه الجمل لن تحصل على فرصة للتنفيذ.
خامسًا:إذا قام طريقة واحدة بتسمية طريقة أخرى تُلقي استثناءً مُعلنًا، فإن الطريقة الأولى يجب أن تتعامل مع الاستثناء أو تُعلن عنه.
2.2 فرق بين throw و throws:
يستخدم throw لقضاء استثناء، ويكون داخل جسم الطريقة. النمط النحوي هو: throw استثناء.
يستخدم throws لتحديد أن الطريقة قد تُلقي استثناءً ما، ويكون في نهاية اسم الطريقة، ويكون النمط النحوي هو:
throws نوع الاستثناء1، نوع الاستثناء2...نوع الاستثناءn.
ثالثًا: يُظهر ما يلي بعض الحالات المحتملة لحدوث استثناء Null Pointer ووسائل الحل المناسبة لها:
جزء من الكود 1:
out.println(request.getParameter("username"));
التحليل:يتمتع جزء الكود 1 بوظيفة بسيطة، وهي إخراج قيمة "username" المدخلة من المستخدم.
الشرح:يبدو أن الجملة أعلاه لا تحتوي على أخطاء نحوية، وغالبًا ما لا تواجه أي مشاكل. ولكن، إذا لم يقدم مستخدم ما قيمة لمجال النموذج "username" عند إدخال البيانات، أو إذا تم تمرير البيانات مباشرة دون الحاجة إلى النموذج، فإن قيمة request.getParameter("username") ستكون فارغة (لا تكن قيمة صحيحة، بل كائن null)، لا يمكن استخدام طريقة println للعنصر out مباشرة على العنصر الفارغ، وبالتالي سيقوم صفحة JSP الموجودة في جزء من الكود 1 بإلقاء استثناء "Java.lang.NullPointerException". بالإضافة إلى ذلك، حتى لو كان العنصر محتمل أن يكون فارغًا، يتم استدعاء بعض العمليات مثل toString()، equal(Object obj) وما إلى ذلك لـ Java.lang.Object أو Object نفسه.
جزء من الكود 2:
String userName = request.getParameter("username"); If (userName.equals("root")) {....}
التحليل:يهدف جزء من الكود 2 إلى فحص اسم المستخدم الذي قدمه المستخدم، إذا كان الاسم هو "root"، فإنه يقوم ببعض العمليات الخاصة.
الشرح:في جزء من الكود 2، إذا لم يقدم المستخدم قيمة لمجال النموذج "username"، فإن كائن 字符串userName يكون له قيمة null، لا يمكنك مقارنة العنصر null مع عنصر آخر مباشرة، وبالتالي، سيقوم صفحة JSP الموجودة في جزء من الكود 2 بإلقاء خطأ Null Pointer Exception.
نصيحة صغيرة:إذا كنت تريد مقارنة قيمة استعادة طريقة مع ثابت، يمكنك وضع الثابت في المقدمة لتجنب استدعاء طريقة equals للعنصر null. على سبيل المثال:
إذا كان ("root".equals(userName)) {....}
حتى إذا كان كائن userName يعود بـ null، فإنه لن يحدث استثناء "NullPointerException" هنا، ويمكنه العمل بشكل طبيعي.
جزء الكود 3:
String userName = session.getAttribute("session.username").toString();
التحليل:وظيفة قطعة الكود 3 هي استخراج قيمة session.username من الجلسة، وتعيين هذه القيمة لجسم السلسلة userName.
الشرح:في الحالات العادية، إذا كان المستخدم قد قام ببعض الجلسات، فإنه لن يواجه أي مشاكل؛ ولكن إذا تم إعادة تشغيل خادم التطبيق بينما لم يعد المستخدم قد قام بالدخول مرة أخرى (أو قد أغلق المستخدم المتصفح ولكن استمر في فتح الصفحة الأصلية.) فإن قيمة الجلسة ستصبح غير صالحة، مما يؤدي إلى أن يكون قيمة session.username في الجلسة فارغة. سيؤدي تنفيذ toString() على كائن null مباشرة إلى إلقاء استثناء "NullPointerException" من النظام.
جزء الكود 4:
public static void main(String args[]){ Person p=null; p.setName("张三"); System.out.println(p.getName()); }
التحليل:إعلان كائن Person وطباعة اسم الكائن.
الشرح:في هذه الحالة، سيظهر لديك استثناء "NullPointerException" لأنك فقط أعلنت عن كائن من النوع Person而没有 إنشاء كائن، لذا لا توجد هناك مرجع للعنصر في الحيوية، لا تنسى أن تكون دائمًا حذرًا عند استدعاء طرق الكائن وأن تنشئ الكائن أولاً.
A: يبدأ باستخدام الكائن مهما كان فارغًا أو غير فارغ.
(JSP) جزء الكود 1:
out.println(request.getParameter("username"));
التحليل:يتمتع جزء الكود 1 بوظيفة بسيطة، وهي إخراج قيمة "username" المدخلة من المستخدم.
الشرح:يبدو أن العبارات أعلاه لا تحتوي على أخطاء نحوية، وفي معظم الحالات لا يواجه أي مشاكل. ولكن، إذا لم يقدم المستخدم قيمة لسمة "username" في إدخال البيانات، أو عبر بعض الطرق لتجاوز النموذج مباشرة وإدخال البيانات، فإن قيمة request.getParameter("username") ستكون فارغة (لاحظ أن هذا ليس حرفًا فارغًا، بل عنصر فارغ null.). لا يمكن استخدام طريقة println من كائن out على كائن فارغ، لذا سيقوم الصفحة JSP التي تحتوي على جزء الكود 1 بإلقاء استثناء "Java.lang.NullPointerException". كما أن حتى إذا كان الكائن محتمل أن يكون فارغًا، فإنه يتم استدعاء بعض طرق Java.lang.Object أو Object نفسه مثل toString()، equal(Object obj) وما إلى ذلك.
(JSP) قطعة الكود 2:
String userName = request.getParameter("username"); If (userName.equals("root")) {....}
التحليل:وظيفة قطعة الكود 2 هي فحص اسم المستخدم الذي قدمه المستخدم، إذا كان الاسم المستخدم هو "root"، فإنه سيتم تنفيذ بعض العمليات الخاصة.
الشرح:في قطعة الكود 2، إذا لم يقدم المستخدم قيمة للمنطقة الخاصة بـ "username" في النموذج، فإن جسم السلسلة userName سيكون له قيمة null، لا يمكن مقارنة جسم null مع جسم آخر مباشرة، وسيتمكن صفحة JSP التي تحتوي على قطعة الكود 2 من إطلاق خطأ نقص المعلومات في الإشارة (Java.lang.NullPointerException).
(JSP) قطعة الكود 3:
String userName = session.getAttribute ("session.username").toString();
التحليل:وظيفة قطعة الكود 3 هي استخراج قيمة session.username من الجلسة، وتعيين هذه القيمة لجسم السلسلة userName.
الشرح:في العادة، إذا كان هناك جلسة مستخدم قد بدأت، فإنه لن يكون هناك أي مشكلة؛ ولكن، إذا تم إعادة تشغيل خادم التطبيق في هذا الوقت، بينما لم يتم تسجيل الدخول المستخدم مرة أخرى (أو حتى إذا كان المستخدم قد أغلق المتصفح، ولكن لا يزال مفتوحًا الصفحة الأصلية.) في هذه الحالة، ستعتمد قيمة الجلسة على أن القيمة الفارغة ستكون قيمة session.username في الجلسة. تنفيذ toString() على جسم null مباشرة سيؤدي إلى إطلاق استثناء (Java.lang.NullPointerException) نقص المعلومات في الإشارة.
هذا هو كل محتوى الحديث البسيط عن معالجة استثناءات نقص المعلومات في Java مع استثناء نقص المعلومات في الإشارة، نأمل أن تدعموا تعليمات النفاد~