Java での Null ポインタ例外

Java の NullPointerException は RuntimeException です。これは、プログラムが null 値を持つオブジェクト参照を使用しようとすると発生します。 Java では、「null」は、値が存在しないことを示すためにオブジェクト参照に割り当てることができる特別な値です。

Null ポインター例外の理由

NullPointerException は、次の理由で発生します。 

  • null オブジェクトからのメソッドの呼び出し。
  • null オブジェクトのフィールドへのアクセスまたは変更。
  • null の長さを配列であるかのように取得します。
  • null オブジェクトのスロットを配列であるかのようにアクセスまたは変更する。
  • null を Throwable 値であるかのようにスローします。
  • Null オブジェクトを介して同期しようとしたとき。

例:

Java
   public     class   Geeks     {          public     static     void     main  (  String  []     args  )     {          // Reference set to null      String     s     =     null  ;             System  .  out  .  println  (  s  .  length  ());         }   }   

出力:

 Hangup (SIGHUP)   
Exception in thread 'main' java.lang.NullPointerException
at Geeks.main(Geeks.java:10)

説明: この例では、文字列参照「s」は null です。プログラムが length() メソッドを呼び出そうとすると、実際のオブジェクトがないため、NullPointerException がスローされます。

Java で null が使用されるのはなぜですか?

null 値はプレースホルダーとして機能し、参照変数に値が割り当てられていないことを示します。一般的なアプリケーションには次のものがあります。

  • リンクされたデータ構造 : リストまたはツリーの分岐の終わりを表します。
  • デザインパターン : これは、Null Object パターンや Singleton パターンなどのパターンで使用されます。

NullPointerException を回避する方法

NullPointerException を回避するには、すべてのオブジェクトが使用前に適切に初期化されていることを確認する必要があります。参照変数を宣言するときは、オブジェクトにメソッドまたはフィールドをリクエストする前に、オブジェクトが null でないことを確認する必要があります。

1.equals() での文字列リテラルの使用

非常に一般的なケースの問題には、文字列変数とリテラルの比較が含まれます。リテラルは、String または Enum の要素の場合があります。 null オブジェクトからメソッドを呼び出す代わりに、リテラルからメソッドを呼び出すことを検討してください。 

例:

Java
   import     java.io.*  ;   class   Geeks     {      public     static     void     main     (  String  []     args  )     {          // Initializing String variable with null value      String     s     =     null  ;      // Checking if s.equals null      try      {      // This line of code throws NullPointerException because s is null      if     (  s  .  equals  (  'gfg'  ))      System  .  out  .  print  (  'Same'  );      else         System  .  out  .  print  (  'Not Same'  );      }      catch  (  NullPointerException     e  )      {      System  .  out  .  print  (  'NullPointerException Caught'  );      }      }   }   

出力
NullPointerException Caught 

NullPointerException を回避するには、オブジェクトではなくリテラルに対して equals を呼び出します。

Java
   import     java.io.*  ;   class   Geeks     {      public     static     void     main     (  String  []     args  )     {          // Initializing String variable with null value      String     s     =     null  ;      // Checking if s is null using try catch      try      {      if     (  'gfg'  .  equals  (  s  ))      System  .  out  .  print  (  'Same'  );      else         System  .  out  .  print  (  'Not Same'  );         }      catch  (  NullPointerException     e  )      {      System  .  out  .  print  (  'Caught NullPointerException'  );      }      }   }   

出力
Not Same 

注記 : null 参照でメソッドが呼び出されるのを避けるために、常にリテラルで equals を呼び出します。

2. メソッドの引数の確認

新しいメソッドの本体を実行する前に、まずその引数が null 値であるかどうかをチェックし、引数が適切にチェックされた場合にのみメソッドの実行を続行する必要があります。それ以外の場合は、IllegalArgumentException がスローされ、渡された引数に問題があることが呼び出しメソッドに通知されます。 

例:

Java
   import     java.io.*  ;   class   Geeks     {      public     static     void     main  (  String  []     args  )     {          // String s set an empty string and calling getLength()      String     s     =     ''  ;          try     {      System  .  out  .  println  (  getLength  (  s  ));      }      catch     (  IllegalArgumentException     e  )     {      System  .  out  .  println  (      'IllegalArgumentException caught'  );      }      // String s set to a value and calling getLength()      s     =     'GeeksforGeeks'  ;          try     {      System  .  out  .  println  (  getLength  (  s  ));      }      catch     (  IllegalArgumentException     e  )     {      System  .  out  .  println  (      'IllegalArgumentException caught'  );      }      // Setting s as null and calling getLength()      s     =     null  ;          try     {      System  .  out  .  println  (  getLength  (  s  ));      }      catch     (  IllegalArgumentException     e  )     {      System  .  out  .  println  (      'IllegalArgumentException caught'  );      }      }      public     static     int     getLength  (  String     s  )      {      if     (  s     ==     null  )      throw     new     IllegalArgumentException  (      'The argument cannot be null'  );          return     s  .  length  ();      }   }   

出力
0 13 IllegalArgumentException caught  

3. 三項演算子の使用

三項演算子を使用すると、NullPointerException を回避できます。最初にブール式が評価されます。式が true の場合は value1 が返され、それ以外の場合は value2 が返されます。 null ポインターを処理するために三項演算子を使用できます。

例:

Java
   import     java.io.*  ;   class   Geeks     {      public     static     void     main  (  String  []     args  )      {      String     s     =     null  ;      String     m     =     (  s     ==     null  )     ?     ''     :     s  .  substring  (  0       5  );      System  .  out  .  println  (  m  );      s     =     'Geeksforgeeks'  ;      m     =     (  s     ==     null  )     ?     ''     :     s  .  substring  (  0       5  );      System  .  out  .  println  (  m  );      }   }   

出力
Geeks  

説明 : 三項演算子は、null をチェックし、null 参照に対する操作を回避するのに役立ちます。

4. オプションのクラスの使用 (Java 8+)

Java 8 では、Optional クラスが、非 null 値を含む場合と含まない場合があるコンテナ オブジェクトとして導入されました。回避に役立ちます NullPointerException 値が存在しない場合に強制的に明示的に処理することによって。

例:

Java
   import     java.util.Optional  ;   public     class   OptionalExample     {      public     static     void     main  (  String  []     args  )     {      Optional   <  String  >     name     =     Optional  .  ofNullable  (  null  );      // Safe way to access      System  .  out  .  println  (  name  .  orElse  (  'Default Name'  ));     // prints: Default Name      }   }   

出力
Default Name  

説明: Optional.ofNullable(value) は、null の可能性がある値をラップします。 orElse() は、値が存在しない場合のフォールバックを提供します。