במדריך זה, אנו הולכים ללמוד את חריג המצביע Null ב-Java. חריג מצביע Null הוא חריג בזמן ריצה. Null הוא סוג מיוחד של ערך שניתן להקצות להתייחסות של אובייקט. בכל פעם שמנסה להשתמש בהפניה בעלת הערך Null, ה-NullPointerException מועלה.
תרחישים שונים עבור חריג ה-Null Pointer
שים לב לכמה מהתרחישים הבאים שבהם ניתן להעלות את NullPointerException.
- חישוב הגודל או האורך של Null כאילו הוא מערך של אלמנטים.
שם קובץ: ThrowNullExcep.java
fcfs
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); } }
תְפוּקָה:
חריגה בשרשור 'main' java.lang.NullPointerException: לא ניתן לקרוא את אורך המערך כי '' הוא null ב-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)
דרישה של ערך NULL
null הוא ערך מיוחד שנמצא בשימוש ב-Java. בדרך כלל משתמשים בו כדי להראות שאין ערך שמוקצה למשתנה הייחוס. ערך null משמש בעיקר ביישום של מבני נתונים כגון רשימה מקושרת או עץ. הוא משמש גם בתבנית Singleton.
נמר לעומת אריה
הימנעות מ-NullPointerException
על מנת להימנע מה-NullPointerException, יש לוודא שהאתחול של כל האובייקטים נעשה כראוי לפני שניתן להשתמש בהם. כאשר מכריזים על משתנה התייחסות, יש לוודא שהערך null אינו מוקצה להפניה לפני שערך ההתייחסות משמש לגישה לשדה או לשיטה.
שים לב לבעיות הנפוצות הבאות עם הפתרון.
תיק 1: השוואה של מחרוזות עם המילולי
אחת הבעיות הנפוצות כוללת השוואה של ליטרלי עם משתנה String. המילולי יכול להיות אלמנט מ-Enum או מ-String. במקום להפעיל את השיטה מהאובייקט null, שקול להפעיל אותה באמצעות המילה המילולי.
שם קובץ: NullPntrExcption.java
css מרכז תמונה
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: לפקוח עין על טיעוני השיטה
יש לבדוק תחילה את ארגומנטי השיטה עבור ערכי null ולאחר מכן ללכת עם ביצוע השיטה. אחרת, יש סיכויים הוגנים שזה יזרוק 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(); } }
תְפוּקָה:
תאריך java למחרוזת
0 3 IllegalArgumentException has been caught. java.lang.IllegalArgumentException: The argument can never be null.
מקרה 3: שימוש ב-Ternary Operator
אפשר גם להשתמש באופרטור הטרינרי כדי להימנע מה-NullPointerException. בשלישית, הביטוי הבוליאני מוערך ראשון. אם הביטוי מוערך כ-true, אז ה-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