J'ai une liste de String
s, et je veux les concaténer avec des espaces entre les deux. Donc, j'utilise StringBuilder
. Maintenant, si l'un des String
s est null
, ils sont stockés dans la StringBuilder
littéralement comme 'null'. Voici un petit programme pour illustrer le problème:
public static void main(String ss[]) {
StringBuilder sb = new StringBuilder();
String s;
s = null;
System.out.println(sb.append("Value: ").append(s));
}
Je m'attendrais à ce que la sortie soit "Value:" mais elle sort comme "Value: null"
Y a-t-il un moyen de contourner ce problème?
Vous pouvez vérifier l'objet avant de l'ajouter:
sb.append("Value: ");
if (s != null) sb.append(s);
System.out.println(sb);
Un point clé à souligner est que null n’est pas la même chose qu’une chaîne vide. Une chaîne vide est toujours un objet chaîne avec des méthodes et des champs associés, un pointeur null n'étant pas du tout un objet.
De la documentation de la méthode append de StringBuilder:
Les caractères de l'argument String sont ajoutés, dans l'ordre, en augmentant la longueur de cette séquence de la longueur de l'argument. Si str est null, les quatre caractères "null" sont ajoutés.
Je ne sais pas pourquoi vous vous attendez à ce qu'il soit vide, étant donné que la documentation est assez claire:
Si str est null, les quatre caractères "null" sont ajoutés.
En gros, vous devez soit ne pas appeler add du tout si vous avez une référence null, soit changer la valeur pour "".
Vous pouvez écrire une méthode pour effectuer cette substitution si vous vous trouvez souvent en train de le faire:
public static String nullToEmpty(String text) {
return text == null ? "" : text;
}
En effet, je viens de regarder la documentation Guava et la classe Strings
a exactement cette méthode (mais avec un paramètre appelé string
au lieu de text
).
Vous pouvez utiliser StringUtils#defaultString()
: de commons-lang
sb.append("Value: ").append(StringUtils.defaultString(myVar));
En une ligne, vous pouvez faire:
System.out.println(sb.append("Value: ").append((s==null)?"":s));
Comme indiqué par @Shynthriir, le contrôle nul est le moyen le plus simple et le plus efficace (AFAIK) pour résoudre le problème.
Cependant, je recommanderais vivement de commencer les chaînes avec une chaîne vide String str = "";
, ce qui vous éviterait beaucoup de maux de tête dans un effort de programmation plus complexe.
Pour mon but, j'avais besoin de généraliser un peu la réponse n ° 2 . Voici la même fonction, prenant Object comme argument, au lieu de String:
private String nullToEmpty(Object obj) {
return obj == null ? "" : obj.toString();
}