NullPointerException は、Java コードで最も一般的な例外です。私は、その最も可能性の高いシナリオを次の 5 つのタイプに分類します:
パラメータ値は、Integer などのパッケージ化タイプです。自動アンボックス化中に null ポインター例外が発生しました;
文字列比較中に null ポインター例外が発生しました;
ConcurrentHashMap などのコンテナーは、 Key と Value が null をサポートしていないため、null Key または Value を強制的に配置すると null ポインタ例外が発生します;
A オブジェクトには B が含まれています。オブジェクト、フィールドは空とは判断されません。B のメソッドをカスケードで呼び出すと null ポインタ例外が発生します。メソッドまたはリモート サービスから返される List は空ではなく null で、List を直接呼び出すと null ポインタ例外が発生します。 null チェックを実行せずにメソッドを実行します。
private List<String> wrongMethod(FooService fooService, Integer i, String s, String t) { log.info("result {} {} {} {}", i + 1, s.equals("OK"), s.equals(t), new ConcurrentHashMap<String, String>().put(null, null)); if (fooService.getBarService().bar().equals("OK")) log.info("OK"); return null; } @GetMapping("wrong") public int wrong(@RequestParam(value = "test", defaultValue = "1111") String test) { return wrongMethod(test.charAt(0) == '1' ? null : new FooService(), test.charAt(1) == '1' ? null : 1, test.charAt(2) == '1' ? null : "OK", test.charAt(3) == '1' ? null : "OK").size(); } class FooService { @Getter private BarService barService; } class BarService { String bar() { return "OK"; } }
Integer の null 判定の場合、Optional.ofNullable を使用して Optional、 orElse(0 ) を使用します。 null をデフォルト値に置き換えて、1 つの操作を実行します。文字列とリテラルの比較では、"OK".equals(s) のようにリテラルを先頭に置くことができるため、s が null の場合でも null ポインタ例外は発生しません。 null 等しい比較には、null 処理を実行する Objects.equals を使用できます。
ConcurrentHashMap の場合、Key も Value も null をサポートしていないため、修正方法は null を格納しないことです。 HashMap の Key と Value は null を格納できますが、ConcurrentHashMap は HashMap のスレッドセーフ版のようですが、null 値の Key と Value をサポートしていないため、この点で誤解が生じやすいところです。
fooService.getBarService().bar().equals("OK") のようなカスケード呼び出しでは、fooService メソッドや getBarService() メソッドなど、null 判定が必要な場所が数多くあります。の戻り値、および bar メソッドによって返される文字列。 if-else を使用して null をチェックする場合は、数行のコードが必要になる場合がありますが、Optional を使用する場合は 1 行のコードで十分です。
rightMethod で返される List については、null かどうか確認できないため、size メソッドを呼び出してリストのサイズを取得する前に、Optional.ofNullable を使用してラップすることもできます。 orElse(Collections.emptyList()) は、List が null の場合に空の List を取得し、最後に size メソッドを呼び出します。
private List<String> rightMethod(FooService fooService, Integer i, String s, String t) { log.info("result {} {} {} {}", Optional.ofNullable(i).orElse(0) + 1, "OK".equals(s), Objects.equals(s, t), new HashMap<String, String>().put(null, null)); Optional.ofNullable(fooService) .map(FooService::getBarService) .filter(barService -> "OK".equals(barService.bar())) .ifPresent(result -> log.info("OK")); return new ArrayList<>(); } @GetMapping("right") public int right(@RequestParam(value = "test", defaultValue = "1111") String test) { return Optional.ofNullable(rightMethod(test.charAt(0) == '1' ? null : new FooService(), test.charAt(1) == '1' ? null : 1, test.charAt(2) == '1' ? null : "OK", test.charAt(3) == '1' ? null : "OK")) .orElse(Collections.emptyList()).size(); }
ビジネス ニーズに応じて、名前、年齢、ニックネームをそれぞれ更新します。名前については、クライアントが名前を null にリセットしたいと考えていると考えられます。 null. を渡すと、このような操作が可能になり、Optional の orElse メソッドを使用して、ワンクリックで null を空の文字列に変換します。
年齢については、クライアントが年齢を更新したい場合は、有効な年齢を渡す必要があると考えられます。年齢のリセット操作はありません。次の場合は、オプションの orElseThrow メソッドを使用できます。値が空の場合、IllegalArgumentException がスローされます。
ニックネームについては、データベース内の名前を null にすることはできないため、ゲストにデータベースから取得した名前を加えたものをニックネームに安全に設定できます。
以上がJavaでnullポインタ例外を処理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。