2013-06-26 63 views
5

怎麼回事?StringBuilder將null附加爲「null」

StringBuilder sb = new StringBuilder(); 

    sb.append("Hello"); 
    sb.append((String)null); 
    sb.append(" World!"); 
    Log.d("Test", sb.toString()); 

主要生產

06-25 18:24:24.354:d /測試(20740):Hellonull世界!

我希望追加null字符串不附加在所有!
順便說一下,鑄造到String是必要的,因爲StringBuilder.append()有很多重載版本。

我簡化了我的代碼,使一個點在這裏,在我的代碼有返回一個字符串

public String getString() { ... } 
... 
sb.append(getString()); 
... 

getString()有時會返回null的方法;現在我必須測試它,如果我想使用StringBuilder !!!!

此外,讓我們在這裏澄清我的問題:我如何獲得StringBuilder.append()以優雅的方式接受空字符串,而不是將其轉換爲文字字符串「null」。
通過優雅我的意思是我不想得到字符串,測試它是否是null,然後才附加它。我正在尋找一個優雅的oneliner。

+0

可能重複的[StringBuilder append()和空值](http://stackoverflow.com/questions/3960712/stringbuilder-append-and-null-values) –

回答

4

就是這樣。 null作爲"null"附加。同樣,當您打印nullSystem.out.println(null)您打印"null"

避免的方法是返回字符串getString()檢查null該方法:

public String getString() { 
    ... 
    if (result == null) { 
     return ""; 
    } 
} 
5
How come? 

及其clearly written in docs

String參數的追加,在順序,由參數的長度增加該序列的長度的字符。如果str爲空,則會追加四個字符「null」。

所以請在追加之前進行空檢查。

+1

好的,它寫在文檔中。但是,這僅僅是我的違反直覺嗎?我瞭解到,空字符串是不存在的字符串。沒有開始討論,我只是不明白爲什麼他們這樣做。現在我正在把桌子上的頭撞到我的頭上。 – ilomambo

+1

我認爲你混淆了null和空字符串。正如你所說(String)null是一個不存在的字符串,它在String域中由「null」表示。另一方面,空字符串「」無意外地具有表示「」。當您調試或打印某些字符串變量時,您希望實際看到它指向空值,因此它是有意義的。 – LastFreeNickname

+0

@LastFreeNickname不是真的,當一個字符串是'null'我不希望/期望什麼都看不到。如果我使用調試器,我想檢查變量並將它的值看作'null'。看起來不久之前,在代數學課程中,教授說有一個特殊的符號來表示一個空集,一個根本沒有任何元素的集,這是一個空字符串的模擬。顯示空字符串的內容與'null'的定義完全一致。但是,這是對溢出的牛奶哭,有一天我希望瞭解原因。 – ilomambo

0

怎樣編寫的實用方法類似

public static void appendString(StringBuilder sb, String st) { 
    sb.append(st == null ? "" : st); 
} 

或該三元運算符是非常方便的。

0
String nullString = null; 
StringBuilder sb = new StringBuilder(); 
sb.append("Hello"); 
if (nullString != null) sb.append(nullString); 
sb.append(" World!"); 
Log.d("Test", sb.toString()); 

有!我做了一行:)

+1

:-)毫無疑問,它是非常優雅的:-) – ilomambo

2

它的行爲就像這樣,因爲null不是一個空的String正如你想象的那樣。空的String將是new String("");。如果獲得null值作爲參數,基本上append()方法會附加"null"

+0

我沒有說「空字符串」我說「一個字符串不存在」 – ilomambo

0

一行嗎?

sb.append((getString()!=null)?getString():""); 

完成。不過是毫無意義的要叫getString()兩次

至於有人提出構建支票存入getString()方法

1

AbstractStringBuilder類通過追加方法String.valueOf(obj)這又轉換成空字符串文字「空」的對象。因此,沒有內在的方法可以幫助你。正如其他人所建議的,您必須在追加方法內使用三元運算符或編寫實用程序方法來處理它。

2

編輯
previous answer沒有反映如要求通過OP對的StringBuilder的這種行爲適當的理由。由於@Stephen下指出

我希望追加一個空字符串不會追加在所有!

但它是追加。究其原因,StringBuilder這種行爲被隱藏在append(Object obj)方法這需要我們其被定義爲AbstractStringBuilder#append(String str)方法的實現細節如下:

public AbstractStringBuilder append(String str) { 
    if (str == null) str = "null"; -->(1) 
    //....... 
    return this; 
} 

它清楚地指定,如果輸入String是空值,則它被改變爲字符串文字「空」,然後進一步處理。

如何讓StringBuilder.append()以優雅的方式接受空字符串,而不是將其轉換爲文字字符串「null」。

您需要明確檢查給定Stringnull,然後繼續。例如:

String s = getString(); 
StringBuffer buf = new StringBuffer(); 
//Suppose you want "Hello "<value of s>" world" 
buf.append("Hello "); 
buf.append(s==null?" world" : s+" world"); 
+0

嚴格來說,JLS並不是明確的。 JLS實際上是指定「+」運算符的語義。你可能會認爲'StringBuilder.append(null)'實現了所需的行爲是一個很方便的巧合。 (我敢肯定這不是巧合,但你明白我的觀點......) –

+0

@StephenC:是的,你是對的..我的錯誤.. –

1

這會爲你工作

public static String getString(StringBuilder sb, String str) { 
    return sb.append(str == null ? "" : str).toString(); 
} 
0

你也可以寫裝飾爲StringBuilder的,它可以檢查任何你想要的:使用的

class NotNullStringBuilderDecorator { 

    private StringBuilder builder; 

    public NotNullStringBuilderDecorator() { 
     this.builder = new StringBuilder(); 
    } 

    public NotNullStringBuilderDecorator append(CharSequence charSequence) { 
     if (charSequence != null) { 
      builder.append(charSequence); 
     } 

     return this; 
    } 

    public NotNullStringBuilderDecorator append(char c) { 
     builder.append(c); 

     return this; 
    } 

    //Other methods if you want 

    @Override 
    public String toString() { 
     return builder.toString(); 
    } 
} 

例子:

NotNullStringBuilderDecorator sb = new NotNullStringBuilderDecorator(); 
sb.append("Hello"); 
sb.append((String) null); 
sb.append(" World!"); 

System.out.println(sb.toString()); 

W ith這個解決方案你不必改變POJO類。