logo

استثناء المؤشر الفارغ في جافا

في هذا البرنامج التعليمي، سوف نتعلم استثناء المؤشر Null في Java. استثناء المؤشر الفارغ هو استثناء وقت التشغيل. Null هو نوع خاص من القيمة التي يمكن تخصيصها لمرجع كائن ما. عندما يحاول أحد استخدام مرجع له القيمة Null، يتم رفع NullPointerException.

سيناريوهات مختلفة لاستثناء المؤشر الفارغ

لاحظ بعض السيناريوهات التالية حيث يمكن رفع NullPointerException.

  • حساب حجم أو طول Null كما لو كان مجموعة من العناصر.

اسم الملف: ThrowNullExcep.java

 public class ThrowNullExcep { // main method public static void main(String args[]) { int arr[] = null; // array is assigned a null value System.out.println('The length of the array arr is: ' + arr.length); } } 

انتاج:

استثناء في مؤشر الترابط 'الرئيسي' java.lang.NullPointerException: لا يمكن قراءة طول الصفيف لأن '' فارغ في ThrowNullExcep.main(ThrowNullExcep.java:7)
  • استدعاء أسلوب باستخدام الكائن الذي له القيمة Null.

اسم الملف: ThrowNullExcep1.java

 public class ThrowNullExcep1 { public void foo() { System.out.println('In the method foo.'); } public static void main(String args[]) { ThrowNullExcep1 obj = null; // assigning null value // invoking the method foo() obj.foo(); } } 

انتاج:

 Exception in thread 'main' java.lang.NullPointerException: Cannot invoke 'ThrowNullExcep1.foo()' because '' is null at ThrowNullExcep1.main(ThrowNullExcep1.java:13) 
  • عند محاولة المزامنة عبر كائن NULL.

اسم الملف: ThrowNullExcep2.java

 // A Java program that synchronizes over a NULL object. import java.util.*; import java.io.*; // A Class that is required for sending the message class Sendr { public void sendMethod(String mssg) { System.out.println('Sending message: ' + mssg ); try { Thread.sleep(100); } catch (Exception exp) { System.out.println('Thread interrupted.' + exp); } System.out.println('
' + mssg + ' is sent'); } } // A Class that is used to send messages with the help of threads Threads class ThreadSend extends Thread { private String mssg; Sendr sendr; // Received a messge obj and the string // mssge that has to be sent ThreadSend(String mStr, Sendr obj) { mssg = mStr; sendr = obj; } public void run() { // Only a single thread is allowed to send a message // at a time. synchronized(sendr) { // synchronizing the send object sendr.sendMethod(mssg); } } } // Driver class public class ThrowNullExcep2 { // main method public static void main(String args[]) { Sendr sendObj = null; ThreadSend Sth1 = new ThreadSend( ' Hello ' , sendObj ); ThreadSend Sth2 = new ThreadSend( ' Bye Bye ' , sendObj ); // Starting the two threads of the ThreadedSend type Sth1.start(); Sth2.start(); // waiting for the threads to end try { Sth1.join(); Sth2.join(); } catch(Exception exp) { System.out.println('Interrupted : ' + exp); } } } 

انتاج:

 Exception in thread 'Thread-0' Exception in thread 'Thread-1' java.lang.NullPointerException: Cannot enter synchronized block because 'this.sendr' is null at ThreadSend.run(ThrowNullExcep2.java:42) java.lang.NullPointerException: Cannot enter synchronized block because 'this.sendr' is null at ThreadSend.run(ThrowNullExcep2.java:42) 
  • بدلاً من رمي قيمة، يتم طرح Null.

اسم الملف: ThrowNullExcep3.java

 // Modifying or accessing the fields of the Null object. public class ThrowExcep3 { int a; // main method public static void main(String args[]) { // assigning a null value ThrowExcep3 obj = null; obj.a = 3; } } 

انتاج:

 Exception in thread 'main' java.lang.NullPointerException: Cannot assign field 'a' because '' is null at ThrowExcep3.main(ThrowExcep3.java:10) 

متطلبات القيمة الخالية

القيمة الخالية هي قيمة خاصة يتم استخدامها في Java. يتم استخدامه عادةً لإظهار أنه لا توجد قيمة تم تعيينها للمتغير المرجعي. تُستخدم القيمة الخالية بشكل أساسي في تنفيذ هياكل البيانات مثل القائمة المرتبطة أو الشجرة. يتم استخدامه أيضًا في نمط Singleton.

تجنب NullPointerException

لتجنب NullPointerException، يجب التأكد من أن تهيئة جميع الكائنات تتم بشكل صحيح قبل أن تتمكن من استخدامها. عندما يعلن أحد عن متغير مرجعي، يجب التحقق من عدم تعيين القيمة الخالية للمرجع قبل استخدام القيمة المرجعية للوصول إلى الحقل أو الأسلوب.

لاحظ المشاكل الشائعة التالية مع الحل.

حالة 1: مقارنة السلاسل مع الحرفي

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

اسم الملف: NullPntrExcption.java

 import java.io.*; public class NullPntrExcption { // main method public static void main (String[] args) { // Initializing a String variable with a null value String pntr = null; // Checking if pntr.equals null or works fine. try { // The following line of code will raise the NullPointerException // It is because the pntr is null if (pntr.equals('JTP')) { System.out.print('String are the same.'); } else { System.out.print('Strinng are not the same.'); } } catch(NullPointerException e) { System.out.print('NullPointerException has been caught.'); } } } 

انتاج:

 NullPointerException has been caught. 

الآن دعونا نرى كيف يمكن للمرء تجنب ذلك.

اسم الملف: NullPntrExcption1.java

 public class NullPntrExcption1 { // main method public static void main (String[] args) { // Initializing a String variable with a null value String pntr = null; // Checking if pntr.equals null or works fine. try { // Now, the following line of code will not raise the NullPointerException // It is because the string literal is invoking the equals() method if ('JTP'.equals(pntr)) { System.out.print('String are the same.'); } else { System.out.print('Strinng are not the same.'); } } catch(NullPointerException e) { System.out.print('NullPointerException has been caught.'); } } } 

انتاج:

 NullPointerException has been caught. 

الحالة 2: مراقبة حجج الطريقة

قائمة المصفوفات في جافا

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

اسم الملف: NullPntrExcption2.java

 // A program for demonstrating that one must // check the parameters are null or not before // using them. import java.io.*; public class NullPntrExcption2 { public static void main (String[] args) { // String st is an empty string and invoking method getLength() String st = ''; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught.'); } // String s set to a value and invoking method getLength() st = 'JTP'; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught.'); } // Setting st with a value null and invoking method getLength() st = null; try { System.out.println(getLength(st)); } catch(IllegalArgumentException exp) { System.out.println('IllegalArgumentException has been caught. ' + exp); } } // method taht computes the length of a string st. // It throws and IllegalArgumentException, if st is null public static int getLength(String st) { if (st == null) { throw new IllegalArgumentException('The argument can never be null.'); } return st.length(); } } 

انتاج:

 0 3 IllegalArgumentException has been caught. java.lang.IllegalArgumentException: The argument can never be null. 

الحالة 3: استخدام المشغل الثلاثي

يمكن للمرء أيضًا استخدام العامل الثلاثي لتجنب NullPointerException. في النظام الثلاثي، يتم تقييم التعبير المنطقي أولاً. إذا تم تقييم التعبير على أنه صحيح، فسيتم إرجاع val1. بخلاف ذلك، يتم إرجاع val2.

اسم الملف: NullPntrExcption3.java

 // A program for demonstrating the fact that // NullPointerException can be avoided using the ternary operator. import java.io.*; public class NullPntrExcption3 { // main method public static void main (String[] args) { // Initializing String variable with null value String st = null; String mssge = (st == null) ? 'String is Null.' : st.substring(0, 5); System.out.println(mssge); // Initializing the String variable with string literal st = 'javaTpoint'; mssge = (st == null) ? '' : st.substring(0, 10); System.out.println(mssge); } } 

انتاج:

 String is Null. javaTpoint