String
sのリストがあり、それらを間にスペースで連結したいと思います。だから私はStringBuilder
を使用しています。 String
のいずれかがnull
である場合、StringBuilder
に文字通り 'null'として格納されます。問題を説明する小さなプログラムを次に示します。
public static void main(String ss[]) {
StringBuilder sb = new StringBuilder();
String s;
s = null;
System.out.println(sb.append("Value: ").append(s));
}
出力は「Value:」になるはずですが、「Value:null」として出力されます
この問題を回避する方法はありますか?
追加する前にオブジェクトをチェックできます。
sb.append("Value: ");
if (s != null) sb.append(s);
System.out.println(sb);
重要なポイントは、nullは空の文字列と同じではないということです。空の文字列は、関連付けられたメソッドとフィールドが関連付けられたStringオブジェクトであり、nullポインターはオブジェクトではありません。
StringBuilderのappendメソッドのドキュメントから:
文字列引数の文字は順番に追加され、このシーケンスの長さを引数の長さだけ増やします。 strがヌルの場合、「ヌル」の4文字が追加されます。
documentation が非常に明確であることを考えると、なぜあなたはそれが空になると予想するのか分かりません:
Strがヌルの場合、「ヌル」の4文字が追加されます。
基本的に、null参照がある場合は、appendをまったく呼び出さないか、 ""の値を切り替える必要があります。
頻繁に行う場合は、この置換を行うメソッドを作成できます。
public static String nullToEmpty(String text) {
return text == null ? "" : text;
}
実際、 Guava のドキュメントを見て、 Strings
クラスにはまさにそのメソッドがあります(ただし、string
と呼ばれるパラメーターを使用しています) text
)の代わりに)。
Commons-langの StringUtils#defaultString()
を使用できます。
sb.append("Value: ").append(StringUtils.defaultString(myVar));
Java 8では、Java.util.Optionalクラスを使用してデフォルト値を提供することもできます。
System.out.println(sb.append("Value: ").append(Optional.ofNullable(s).orElse("")));
1行で次のことができます。
System.out.println(sb.append("Value: ").append((s==null)?"":s));
@Shynthriirが述べたヌルチェックは、問題を回避するための最も簡単で最も効率的な方法(AFAIK)です。
ただし、代わりに空の文字列String str = "";
で文字列を開始することを強くお勧めします。これにより、より複雑なプログラミング作業で多くの頭痛の種が軽減されます。
私の目的のために、回答#2を少し一般化する必要がありました。以下は、ストリングではなくオブジェクトを引数として使用する同じ関数です。
private String nullToEmpty(Object obj) {
return obj == null ? "" : obj.toString();
}