what is nullpointerexception java how avoid it
このチュートリアルでは、JavaのNullPointerExceptionについてすべて説明します。ヌルポインタ例外の原因とそれを回避する方法について説明します。
JavaのNullPointerExceptionは実行時の例外です。 Javaは、オブジェクト参照に特別なnull値を割り当てます。プログラムがnull値に設定されたオブジェクト参照を使用しようとすると、この例外がスローされます。
=> ここで簡単なJavaトレーニングシリーズに注意してください。
学習内容:
JavaでのNullPointerException
null値を持つオブジェクト参照がNullPointerExceptionをスローする場合、なぜnull値が必要なのですか?
null値は通常、参照変数に値が割り当てられていないことを示すために使用されます。次に、nullノードを示すために、リンクリストやツリーなどのコレクションにnull値が必要です。シングルトンパターンのようなデザインパターンは、null値を利用します。
結論として、Javaのnull値には多くの用途があります。 Javaの特定のシナリオでは、Null PointerExceptionがスローされます。
いくつかのシナリオは次のとおりです。
- nullオブジェクトを使用して呼び出されるメソッド。
- nullオブジェクトのフィールドまたはデータメンバーへのアクセスまたは変更。
- nullオブジェクトを引数としてメソッドに渡します。
- null配列の長さを計算します。
- null配列のインデックスにアクセスします。
- nullオブジェクトを同期しています。
- nullオブジェクトをスローします。
Null Pointer Exceptionは、RuntimeExceptionクラスから拡張されています。
NullPointerExceptionの階層を以下に示します。
上記の階層に示されているように、Null Pointer Exceptionは、Exceptionクラスを継承するRuntimeExceptionから拡張されます。例外クラスは、ObjectのサブクラスであるThrowableクラスから派生します。
java.lang.NullPointerExceptionの発生の原因
ここで、上記のNullPointerException発生の各シナリオを示します。
#1)メソッドはnullオブジェクトを使用して呼び出されます
次のコード例を検討してください。ここに、2つのメソッドを提供するクラスMyClassがあります。最初のメソッド「initT」はnullオブジェクトを返します。 mainメソッドでは、initTメソッドを呼び出してMyClassのオブジェクトを作成します。
次に、MyClassのprintメソッドを呼び出します。ここでは、nullオブジェクトを使用してprintメソッドを呼び出しているときに、java.lang.NullPointerExceptionがスローされます。
class MyClass { public static MyClass initT() { //method returns a null object return null; } public void print(String s) { System.out.println(s.toLowerCase()); } } class Main{ public static void main(String() args) { MyClass t = MyClass.initT(); //create a new object (null object) t.print('Hello, World!'); //invoke method using null object } }
出力
#2)nullオブジェクトのアクセスフィールド
class MyClass { int numField = 100; public static MyClass initT() { //method returns a null object return null; } public void print(String s) { System.out.println(s.toLowerCase()); } } class Main{ public static void main(String() args) { MyClass t = MyClass.initT(); //create a new object (null object) int num = t.numField; //access MyClass member using null object } }
出力
働くのに最適なゲームスタジオ
これは、NullPointerExceptionのもう1つの原因です。ここでは、nullオブジェクトを使用してクラスメンバーにアクセスしようとします。 initTメソッドの戻り値をオブジェクトtに割り当ててから、オブジェクトtを使用してnumFieldにアクセスします。ただし、initTはnullオブジェクトを返すため、オブジェクトtはnullオブジェクトです。この時点で、java.lang.NullPointerExceptionが発生します。
#3)引数としてnullオブジェクトを渡す
これは、java.lang.NullPointerExceptionが発生する一般的な原因です。次のJavaプログラムについて考えてみます。ここに、引数として渡されたStringオブジェクトを小文字に変換するメソッド「print_LowerCase」があります。
public class Main { public static void print_LowerCase(String s) { System.out.println(s.toLowerCase()); } public static void main(String() args) { print_LowerCase(null); //pass null object as argument to the method } }
出力
mainメソッドでは、このメソッドを呼び出し、引数としてnullを渡します。 Stringオブジェクトをnullにすることはできないため、java.lang.NullPointerExceptionがスローされます。
#4)null配列の長さを取得する
null配列の長さを計算しようとすると、java.lang.NullPointerExceptionもスローされます。
以下のプログラムはこれを示しています。
public class Main { public static void main(String() args) { int() dataArray = null; //Array is null; no data System.out.println('Array Length:' + dataArray.length); //print array length } }
出力
上記のプログラムでは、配列を宣言し、それにnullを割り当てます。つまり、データはありません。このnull配列でlengthプロパティを使用すると、NullPointerExceptionがスローされます。
#5)null配列のアクセスインデックス
長さと同様に、インデックスを使用してnull配列の値にアクセスしようとしても、java.lang.NullPointerExceptionの原因になります。
public class Main { public static void main(String() args) { int() dataArray = null; //Array set to null //access value at index 2 System.out.println('Value at index 2:' + dataArray(2)); } }
出力
上記のプログラムでは、null配列のインデックス2の値にアクセスしようとします。
#6)nullオブジェクトでの同期
通常、ブロックまたはメソッドを同期して、同時アクセスを容易にします。ただし、同期に使用するオブジェクト参照はnullであってはなりません。 nullオブジェクトの場合、java.lang.NullPointerExceptionが発生します。
以下のJavaプログラムはこれを示しています。ご覧のとおり、Stringオブジェクト「mutex」がnullに初期化されています。次に、main関数で、オブジェクト参照としてミューテックスを使用して同期ブロックを使用します。ミューテックスがnullであるため、java.lang.NullPointerExceptionが発生します。
public class Main { public static String mutex = null; //mutex variable set to null public static void main(String() args) { synchronized(mutex) { //synchronized block for null mutex System.out.println('synchronized block'); } } }
出力
#7)nullをスローする
public class Main { public static void main(String() args) { throw null; //throw null } }
出力:
上記のサンプルプログラムでは、有効なオブジェクトをスローする代わりに、nullがスローされます。これにより、ヌルポインタ例外が発生します。
ヌルポインタ例外の回避
NullPointerExceptionの発生の原因を確認したので、プログラムでもそれを回避するように努める必要があります。
まず、プログラムで使用するオブジェクトが適切に初期化されていることを確認して、Nullポインター例外が発生するnullオブジェクトの使用を回避できるようにする必要があります。また、プログラムで使用される参照変数が有効な値を指し、誤ってnull値を取得しないように注意する必要があります。
これらの考慮事項とは別に、java.lang.NullPointerExceptionを回避するために、ケースバイケースでさらに注意を払うこともできます。
以下では、いくつかのケースを検討します。
#1)リテラルとの文字列比較
文字列変数とリテラル(列挙型の実際の値または要素)の比較は、Javaプログラムで非常に一般的な操作です。ただし、オブジェクトであるString変数がnullの場合、このnullオブジェクトをリテラルと比較するとNullPointerExceptionがスローされます。
したがって、解決策は、nullになる可能性のあるStringオブジェクトではなく、リテラルから比較メソッドを呼び出すことです。
次のプログラムは、リテラルから比較メソッドを呼び出して、java.lang.NullPointerExceptionを回避する方法を示しています。
class Main { public static void main (String() args) { // String set to null String myStr = null; // Checking if myStr is null using try catch. try { if ('Hello'.equals(myStr)) //use equals method with literal System.out.print('Two strings are same'); else System.out.print('Strings are not equal'); } catch(NullPointerException e) { System.out.print('Caught NullPointerException'); } } }
出力
#2)メソッドの引数をチェックしてください
メソッドの引数をチェックして、それらがnull値でないことを確認します。引数が仕様どおりでない場合、コードはIllegalArgumentExceptionをスローして、引数が期待どおりでないことを示します。
これは、以下のJavaプログラムに示されています。
import java.io.*; class Main { public static void main (String() args) { // set String to empty value String myStr = ''; try { System.out.println('String value:' + myStr); System.out.println('String Length:' + getLength(myStr)); } catch(IllegalArgumentException e) { System.out.println('Exception: ' + e.getMessage()); } // Set String to a proper value and call getLength myStr = 'Far from home'; try { System.out.println('String value:' + myStr); System.out.println('String Length:' + getLength(myStr)); } catch(IllegalArgumentException e) { System.out.println('Exception: ' + e.getMessage()); } // Set String to null and call getLength() myStr = null; try { System.out.println('String value:' + myStr); System.out.println('String Length:' + getLength(myStr)); } catch(IllegalArgumentException e) { System.out.println('Exception: ' + e.getMessage()); } } // Method that returns length of the String public static int getLength(String myStr) { if (myStr == null) //throw Exception if String is null throw new IllegalArgumentException('The String argument cannot be null'); return myStr.length(); } }
出力
#3)null値を処理するための三項演算子の使用
三項演算子を使用して、java.lang.NullPointerExceptionを回避できます。三項演算子には3つの演算子があります。 1つ目は、trueまたはfalseに評価されるブール式です。式がtrueの場合、2番目の演算子が返されるか、3番目の演算子が返されます。
次のプログラムは、NullPointerExceptionを回避するための三項演算子の使用を示しています。
import java.io.*; class Main { public static void main (String() args) { // Initialize String with null value String myStr = null; //return a substring for this String using ternary oprator String myVal = (myStr == null) ? '' : myStr.substring(0,5); if(myVal.equals('')) System.out.println('Empty String!!'); else System.out.println('String value: ' + myVal); // Now set a value for String myStr = 'SoftwareTestingHelp'; //return a substring for this String using ternary oprator myVal = (myStr == null) ? '' : myStr.substring(0,8); if(myVal.equals('')) System.out.println('Empty String!!'); else System.out.println('String value: ' + myVal); }
出力
よくある質問
Q#1)JavaでNullPointerExceptionを修正するにはどうすればよいですか?
回答: プログラムで使用されるすべてのオブジェクトが適切に初期化され、null値がないことを確認する必要があります。また、参照変数にnull値を設定しないでください。
#2)NullPointerExceptionはチェックされていますか、それともチェックされていませんか?
回答: NullPointerExceptionはチェックされた例外ではありません。これはRuntimeExceptionの子孫であり、チェックされていません。
#3)NullPointerExceptionを停止するにはどうすればよいですか?
回答: NullPointerExceptionを回避するためのベストプラクティスのいくつかは次のとおりです。
- nullになる可能性のある不明なオブジェクトで使用する代わりに、文字列リテラルでequals()およびequalsIgnoreCase()メソッドを使用します。
- toString()の代わりにvalueOf()を使用します;どちらも同じ結果を返します。
- Javaアノテーション@NotNullおよび@Nullableを使用します。
#4)Javaのnull値は何ですか?
回答: null値は、オブジェクトまたは変数を参照しません。キーワードでありリテラルです。これはnull参照を表します。
#5)JavaでNullPointerExceptionをキャッチできますか?
回答: 例外java.lang.NullPointerExceptionはチェックされていない例外であり、RuntimeExceptionクラスを拡張します。したがって、プログラマーがそれをキャッチする必要はありません。
結論
このチュートリアルでは、JavaでのNullPointerExceptionについて説明しました。これは非常に危険な例外であり、通常、予期しないときにポップアップする可能性があります。ヌルポインタ例外は、ほとんどの場合、nullオブジェクトまたはnull参照が原因で発生します。 NullPointerExceptionを回避する原因と方法はすでに見てきました。
プログラマーは、可能な限り、プログラムでのNull PointerExceptionの発生を回避するように努める必要があります。これはチェックされていないランタイム例外であるため、アプリケーションの実行中には発生しないことがわかります。
=> ゼロからJavaを学ぶには、ここにアクセスしてください。