このチュートリアルでは、Java の Null ポインター例外について学習します。 Null ポインター例外は実行時例外です。 Null は、オブジェクトの参照に割り当てることができる特別な種類の値です。 Null 値を持つ参照を使用しようとすると、NullPointerException が発生します。
Null ポインター例外のさまざまなシナリオ
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 であるため、配列の長さを読み取れません- Null 値を持つオブジェクトを使用してメソッドを呼び出します。
ファイル名: ThrowNullExcep1.java
npどこ
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
Excelで最初の文字を削除する方法
// 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: 文字列とリテラルの比較
よくある問題の 1 つは、リテラルと文字列変数の比較です。リテラルは、列挙型または文字列の要素にすることができます。 null オブジェクトからメソッドを呼び出す代わりに、リテラルを使用してメソッドを呼び出すことを検討してください。
整数をJavaの倍精度に変換する
ファイル名: NullPntrException.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.
では、それを回避する方法を見てみましょう。
ファイル名: NullPntrException1.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 がスローされ、渡された引数が間違っていることを呼び出し側メソッドに通知する可能性がかなりあります。
chownコマンド
ファイル名: NullPntrException2.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 を回避するために三項演算子を使用することもできます。 3 項では、ブール式が最初に評価されます。式が true と評価されると、val1 が返されます。それ以外の場合は、val2 が返されます。
ファイル名: NullPntrException3.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