JavaでNullPointerExceptionを処理する方法

Javaでプログラムを開発することに時間を費やしたことがある場合、ある時点で、次の例外が確実に発生します。

java.lang.NullPointerException

が原因で、いくつかの主要な生産上の問題が発生しNullPointerExceptionます。この記事ではNullPointerException、Javaで処理するいくつかの方法について説明します。

単純なヌルチェック

次のコードについて考えてみます。

public static void main(String args[]) { String input1 = null; simpleNullCheck(input1); } private static void simpleNullCheck(String str1) { System.out.println(str1.length()); }

このコードをそのまま実行すると、次の例外が発生します。

Exception in thread "main" java.lang.NullPointerException

このエラーが発生する理由は、実行しようとしているためです。 length()上の操作str1ですnull

これを簡単に修正するには、にnullチェックを追加します。 str1以下に示すように:

private static void simpleNullCheck(String str1) { if (str1 != null) { System.out.println(str1.length()); } }

これにより、 str1ですnull、実行しません length()その上で機能します。

しかし、あなたは次の質問があるかもしれません。

str1が重要な変数である場合はどうなりますか?

その場合、次のようなことを試すことができます。

 private static void simpleNullCheck(String str1) { if (str1 != null) { System.out.println(str1.length()); } else { // Perform an alternate action when str1 is null // Print a message saying that this particular field is null and hence the program has to stop and cannot continue further. } }

値がであると予想する場合はnull、そのnull変数をチェックする方がよいという考え方です。そして、値がであることが判明した場合nullは、別のアクションを実行します。

これは、文字列だけでなく、Javaの他のオブジェクトにも適用できます。

Lombokヌルチェック

次の例を見てください。

public static void main(String args[]) { String input2 = "test"; List inputList = null; lombokNullCheck(input2, inputList, input2); } public static void lombokNullCheck(String str1, List strList, String str2) { System.out.println(str1.length() + strList.size() + str2.length()); }

:ここでは、3つの引数を受け取る関数を持っているstr1strListstr2

これらの値のいずれかがであることが判明した場合null、この関数のロジックを実行する必要はありません。

これをどのように達成しますか?

ここでLombokが便利です。コードにLombokライブラリを追加するには、次のMaven依存関係を含めます。

  org.projectlombok lombok 1.18.12 provided 

Mavenの詳細については、この記事を確認してください。

Lomboknullチェックを使用したコードは次のようになります。

public static void main(String args[]) { String input2 = "test"; List inputList = null; try { lombokNullCheck(input2, inputList, input2); } catch (NullPointerException e) { System.out.println(e); } } public static void lombokNullCheck(@NonNull String str1, @NonNull List strList, @NonNull String str2) { System.out.println(str1.length() + strList.size() + str2.length()); }

関数のすべての引数の前に追加します @NonNull注釈。

また、この関数を呼び出すときはtry-catch、catchの関数呼び出しの周りにブロックを配置しますNullPointerException

関数で指定された引数のいずれかがであることが判明した場合null、関数はNullPointerException。をスローします。その後、これはtry-catchブロックによってキャッチされます。

これにより、関数の引数のいずれかがであることが判明した場合null、関数内のロジックが実行されず、コードが異常に動作しないことがわかります。

これは、一連のnullチェックステートメントでも実行できます。ただし、Lombokを使用nullすると、複数のチェックステートメントを記述しないようになり、コードがよりきれいに見えるようになります。

リストとヌル

リストがあり、リスト内のすべての要素を印刷するとします。

List stringList = new ArrayList(); stringList.add("ele1"); stringList.add("ele2"); if (stringList != null) { for (String element : stringList) System.out.println(element); }

リストをループする前nullに、リストにチェックを入れる必要があります。

nullチェックが存在しない場合、nullリストをループしようとすると、がスローされますNullPointerException

マップとヌル

マップ内の特定のキーの値にアクセスする必要があるシナリオを考えてみましょう。

Map testMap = new HashMap(); testMap.put("first_key", "first_val"); if (testMap != null && testMap.containsKey("first_key")) { System.out.println(testMap.get("first_key")); }

まず、マップオブジェクト自体に対してnullチェックを実行する必要があります。これが行われず、マップがnullである場合、aNullPointerExceptionがスローされます。これはを使用して行われますtestMap!=null

それが完了したら、アクセスする前に特定のキーが存在するかどうかを確認してください。を使用してキーの存在を確認できますtestMap.containsKey("first_key")。これが行われず、特定のキーが存在しない場合、値はとして取得されnullます。

常にヌルチェックを追加する必要がありますか?

If you know for certain that a particular variable can never be null, then you can avoid adding the null check. This maybe applicable in private functions where you can control the data going into function.

But if you are not really certain about the nullability of an object, it is best to add a null check.

Code

All the code discussed in this article can be found in this Github repo.

Congrats ?

You now know how handle NullPointerException in Java!

About the author

I love technology and follow advancements in the field. I also like helping others with my knowledge of tech.

Feel free to read more of my articles on my blog, connect with me on LinkedIn, or follow me on Twitter.