1 はじめに
実際のプロジェクトではnullチェックを判定する箇所が多く、nullチェックが行われていない場合はNullPointerExceptionが発生する可能性があります。
例外の処理については、前の記事で説明しました。
実際のプロジェクトにおける空の判定方法をいくつか見てみましょう
通常、オブジェクトが Null かどうかを判断します。java.util の Objects.nonNull(obj)、hutool の ObjectUtil、または直接 null != obj を使用できます。
2. リストの空判定
List のような特殊なプロジェクトでは、単に空ではないと判断される場合があります。List の場合、null に等しくないことと List.size() が 0 に等しくないことは 2 つの異なるものです。社内にはこれら 2 つをよく混同するインターンもいます。list が null に等しくない場合は、初期化されていることを意味します, それに属するヒープ メモリの一部があります。サイト、サイズ 0 は、そこに何も置かれていないことを意味します。たとえば、null に等しくない場合は、現在ボトルがあることを意味します。サイズが 0 より大きい場合は、ボトルに水が入っていることを意味します。
実際のプロジェクトでは list.isEmpty() を使って直接判定していることも確認されていますので、ソースコードを見てみましょう。
これは、ボトルに水があるかどうかを判断するのと同じです(ボトルがすでに存在していることが前提で、ボトルが存在しない場合は NullPointerException がスローされます)。
したがって、通常は list != null && list.size > 0 を使用して判断するか、HuTool の CollUtil ツールの isEmpty を直接使用します。セットやマップなどもあります。
3. 文字列のnull判定
ここではボトルと水の概念がまだ使用されており、String が null の場合に、equals(String) または length() を呼び出すと java.lang.NullPointerException がスローされます。
空の文字列を判断するにはいくつかの方法があります。
1. ほとんどの人が使用する方法の 1 つで、直感的で便利ですが、非効率的です。
if(a == null || a.equals(""));
2. 文字列の長さを効率的に比較します。
if(a == null || a.length() == 0);
3. Java SE 6.0 は提供が開始されたばかりであり、効率は方法 2 と同様です。
if(a == null || a.isEmpty());
もちろん、org.apache.commons.lang.StringUtils ツールを使用することもできます。
StringUtils.isNotBlank(a);
* StringUtils.isNotBlank(null) = false
* StringUtils.isNotBlank("") = false
* StringUtils.isNotBlank(" ") = false
* StringUtils.isNotBlank("ボブ") = true
* StringUtils.isNotBlank(" bob ") = true
ツールクラスには isNotEmpty() メソッドもあります。この 2 つの違いはコメントから明確にわかります。
StringUtils.isNotEmpty(a);
* StringUtils.isNotEmpty(null) = false
* StringUtils.isNotEmpty("") = false
* StringUtils.isNotEmpty(" ") = true
* StringUtils.isNotEmpty("ボブ") = true
* StringUtils.isNotEmpty(" bob ") = true
4、オプション
Optional の外観は、NullpointException を防ぐために使用されます。一般的な方法は次のとおりです。
- .empty(): 空のオプションのインスタンスを作成します。
- .of(T t) : Optional インスタンスを作成し、null の例外を報告します
- .ofNullable(T t): t が null でない場合は、Optional インスタンスを作成し、それ以外の場合は空のインスタンスを作成します。
- isPresent() : コンテナ内に値があるかどうかを判断します。
- ifPresent(Consume lambda): コンテナが空でない場合、かっこ内の Lambda 式を実行します。
- orElse(T t) : コンテナ内の要素を取得します。コンテナが空の場合は、かっこ内のデフォルト値を返します。
- orElseGet(Supplier s): 呼び出し元のオブジェクトに値が含まれている場合はその値を返し、それ以外の場合は s によって取得された値を返します。
- orElseThrow() : 空の場合は、定義された例外をスローし、空でない場合は、現在のオブジェクトを返します。
- map(関数 f): 処理する値がある場合は、処理された Optional を返します。それ以外の場合は、Optional.empty() を返します。
- flatMap(関数マッパー): マップと同様に、戻り値はオプションである必要があります。
- T get() : コンテナ内の要素を取得します。コンテナが空の場合、NoSuchElement 例外がスローされます。
一般的な例を見てみましょう。
BaseInfo クラスには Boolean 属性があります。空の場合は false を返し、空でない場合はその値を受け取ります。4 行が必要です。
Optional を使用すると、1 行で実行でき、非常にエレガントです。
4.1 オプションオブジェクトの作成
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
//可以看到两个构造方格都是private 私有的
//说明 没办法在外面new出来Optional对象
private Optional() {
this.value = null;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
//这个静态方法大致 是创建出一个包装值为空的一个对象因为没有任何参数赋值
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
//这个静态方法大致 是创建出一个包装值非空的一个对象 因为做了赋值
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
//这个静态方法大致是 如果参数value为空,则创建空对象,如果不为空,则创建有参对象
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
}
复制代码
4.2 使用シナリオ
シナリオ 1: サービス層のオブジェクトをクエリし、返された後に空かどうかを判断して処理する
シナリオ 2: オプションの関数型プログラミングを使用し、1 行で完了する
5. まとめ
各メソッドの存在には適用可能なシナリオが必要であり、場合によっては、コードは洗練されていますが、この種のチェーン プログラミングが必要になります。ただし、ロジックはそれほど明瞭ではなく、可読性は低下していますが、プロジェクトの状況に応じて使用できます。