2009-08-14 49 views
39

通常我有一個類這樣:我應該將初始java字符串值從null設置爲「」嗎?

public class Foo 
{ 
private String field1; 
private String field2; 

// etc etc etc 
} 

這使得FIELD1的和等於空的初始值FIELD2。將所有我的字符串類字段如下所示會更好嗎?

public class Foo 
{ 
private String field1 = ""; 
private String field2 = ""; 

// etc etc etc 
} 

然後,如果我符合類定義,我會避免大量的空指針問題。這種方法有什麼問題?

+2

所以沒有什麼'壞'會發生,我只會失去我的Java純度狀態? – Martlark 2009-08-16 04:46:33

+0

當意外的「」字符串與引發的異常一樣有用時,可以發現錯誤。有了這個優勢,你的網絡應用程序不會崩潰,讓你難堪。 – Martlark 2010-07-14 00:10:43

回答

6

我不同意其他海報。使用空字符串是可以接受的。我更喜歡儘可能使用它。

在絕大多數情況下,空字符串和空字符串表示完全相同的東西 - 未知數據。無論您使用空字符串還是空字符串表示,都是一個選擇問題。

+0

你能否請更新如果我們有像List這樣的字符串以外的引用變量。應該用一些列表對象初始化它們以防止NPE – Killer 2017-03-27 09:47:19

+0

@Shubham,好點。集合(列表,集合,映射)是第二種情況,其中使用'空'版本而不是null通常是有意義的。就個人而言,我更喜歡(例如)一個空列表空引用。 – 2017-07-18 00:54:45

48

絕對不是。一個空字符串和一個空字符串是完全不同的東西,你不應該混淆它們。

爲了進一步解釋:

  • 「空」的意思是「我還沒有初始化 這個變量,或者它有沒有價值」
  • 「空字符串」的意思是「我所知道的價值是什麼,它是空的」。

正如Yuliy已經提到的,如果你看到了很多空指針異常的,那是因爲你期待的事情有值時,他們不這樣做,或者你做事馬虎你使用之前初始化的東西他們。無論哪種情況,您都應該花時間進行正確編程 - 確保應具有值的事物具有這些值,並確保如果您訪問的是可能沒有價值的事物的值,那麼將其納入考慮範圍。

+0

我同意;然而(只是作爲魔鬼的擁護者),有些人習慣於鬆散類型的系統,他們可以開始使用未定義的字符串變量,並將其視爲空。 – 2009-08-14 13:55:52

+0

同意,但有些原因可能會導致您初始化字符串。值得向海報解釋兩者的區別。 – doomspork 2009-08-14 13:56:26

+4

@Chris:但是Java並不是一種鬆散類型的語言,所以爲什麼還要花費一半的時間試圖讓它看起來像一個? – Tundey 2009-08-14 17:07:09

1

我會避免這樣做,您需要知道您的實例是否沒有正確填充數據。

66

這種方式是瘋狂(通常)。如果你遇到很多空指針問題,那是因爲你在實際填充它們之前嘗試使用它們。那些空指針問題是大聲討厭的警告警報,告訴你在哪裏使用,讓你進入並解決問題。如果你剛開始時將它們設置爲空,那麼你將冒着使用它們的風險,而不是你實際期望的。

+5

+1,但需要注意的一點是:如果從數據庫填充對象,而該數據庫恰好是Oracle,則將空字符串視爲null。但是,明確地初始化爲「」在這種情況下不會幫助你。 – kdgregory 2009-08-14 14:08:12

6

通常最好避免這種情況。有幾個原因:

  1. 獲得一個NullPointerException異常通常是您使用的是可變的,你應該是前很好的警示,或者說你忘了設置。將它設置爲一個空字符串可以消除NullPointerException,但是可能會導致程序中的錯誤發生,從而導致不同的錯誤(並且難以追蹤)。

  2. null和「」之間可以有一個有效的區別。空值通常表示沒有設置值或值未知。一個空字符串表示它被故意設置爲空。根據您的計劃,這種微妙的差異可能很重要。

7

在特定的情況下,在設置其他位置之前使用的值是否真的有意義,並且在這種情況下表現爲空字符串?即是一個空字符串,它實際上是一個正確的默認值,它是否有意義有一個默認值呢?

如果答案是肯定的,在聲明中將其設置爲「」是正確的做法。如果沒有,這是一個讓錯誤難以發現和診斷的祕訣。

0

沒辦法。你爲什麼想這樣做?這會導致不正確的結果。空值和「」「不一樣

0

空更好,這就是爲什麼它們被稱爲未經檢查的異常{空指針異常}。拋出異常時,它告訴你必須將它初始化爲非空。值調用它的任何方法之前

如果你

私人字符串字段1 =「」;

您試圖剿錯誤是很難找到的bug,後來

2

我不會建議。

相反,你應該給你的領域合理的價值觀。如果他們不需要改變,我會讓他們最終決定。

public class Foo { 
    private final String field1; 
    private final String field2; 
    public Foo(String field1, String field2) { 
     this.field1 = field1; 
     this.field2 = field2; 
    } 
    // etc. 
} 

沒有必要分配,我還沒有初始化,但價值。只要給它初始值。

2

我知道這是一個老問題,但我想指出以下幾點:

String s = null; 

    s += "hello"; 
    System.out.println(s);// this will return nullhello 

String s = ""; 

    s += "hello"; 
    System.out.println(s); // this will return hello 

顯然真正回答這是一個應該用StringBuffer而不是僅僅連接字符串,但我們都知道,對於某些代碼來說,它只是簡化了連接。

+5

有什麼區別?他們看起來和我一樣。 – Martlark 2011-05-03 23:33:21

1

我想當你使用String s = null時,它只會在堆棧上創建變量「s」,堆中不會存在任何對象,但只要你聲明瞭一些東西就像String s =「」;它會做的就像它會在堆上創建對象一樣。我們知道字符串是不可變的,所以每當你爲字符串變量賦值時,它就會在堆上創建新的對象...所以我認爲String s = null比String s =「」更有效率;

歡迎提出建議!!!!!

+0

不,因爲String是不可變的,所以Java足夠聰明,只能創建一個對象「」而只返回另一個對象的引用 – jasg 2017-03-31 13:57:47

相關問題