2011-06-22 79 views
1

我創建了一個自定義ListView適配器/項目。該項目包含一個CheckedTextView和一個TextView。在我的自定義ListView項目上,爲什麼(string.length()<= 0)總是爲true,而(string ==「」)總是爲false?

在適配器的getView()方法中,自定義項目被創建並且它的setTask(Task)方法在返回之前被調用。

setTask(Task)方法獲取2個字符串以及作爲參數傳入的Task對象的布爾值。 (我知道它的地址實際上是通過的。)

其中一個字符串被分配給自定義項目的TextView的文本屬性,如果該字符串包含文本。否則,TextView的可見屬性將設置爲「不存在」。

爲了做出這個決定,我檢查是否字符串的長度小於或等於0 ...它會產生意外的行爲 - 它總是評估真實。

如果我改變它來檢查字符串是否等於「」,它總是返回false。

這使我相信我檢查的字符串爲空。爲什麼會這樣?

protected void onFinishInflate() { 
    super.onFinishInflate(); 
    checkbox = (CheckedTextView)findViewById(android.R.id.text1); 
    description = (TextView)findViewById(R.id.description); 
} 

public void setTask(Task t) { 
    task = t; 
    checkbox.setText(t.getName()); 
    checkbox.setChecked(t.isComplete()); 
    if (t.getDescription().length() <= 0) 
     description.setVisibility(GONE); 
    else 
     description.setText(t.getDescription()); 
} 

而這裏的適配器中getView()方法:

public View getView(int position, View convertView, ViewGroup parent) { 

    TaskListItem tli; 
    if (convertView == null) 
     tli = (TaskListItem)View.inflate(context, R.layout.task_list_item, null); 
    else 
     tli = (TaskListItem)convertView; 

    tli.setTask(currentTasks.get(position)); 
    return tli; 
} 
+0

你的問題是一個典型的教室案例。 –

+0

@保守的怪胎原諒我 - 我是Stack Overflow的新手。這是否意味着它不夠先進?我在這裏做了些什麼皺眉嗎?我現在不在Java課程,從來沒有過,但我是初學者。 – derrik

+0

不,不,完全沒有。說這是一個典型的教室案例,意味着你徹底理解這個案例非常重要。由於對這種情況的理解奠定了您對Java編程語言(以及C#)的理解的基礎。 –

回答

6
myString == "" 

檢查字符串對象的引用而不是內容。您應該使用:

"".equals(myString) 

它檢查字符串的內容,而不是參考。您可以使用:

myString.equals("") 

但如果myString爲null,則有可能發生NullPointerException。

+1

偉大的答案 - 完全清晰和簡潔。謝謝! – derrik

-1

==運算符檢查雙方是否引用同一個對象。兩個具有相同內容的字符串通常不會引用同一個對象,請參見下文。

String s = ""; 
String t = ""; 
if (s == t){ 
    //false! s and t refer to different objects 
} 
if (s.equals(t) && t.equals(s)){ //these two are equivalent 
    //true! 
} 
s = t; 
if (s == t){ 
    //now they refer to the same object, so true! 
} 
+0

我不會稱之爲'對象平等'。這就是.equals()的含義。 ==運算符比較變量引用。 –

+0

確實如此編輯 – Martijn

+0

您是否真的在上面嘗試過您的代碼?即使在將它們賦值爲相同變量之前,s == t實際上也會返回true。 – Kal

2

在Java中,您不能使用==比較String與另一個String的內容。 ==運算符總是比較變量的引用或內存地址。在其他語言中,==可以用來比較對象的內容。在Java中它不能。使用.equals()或.equalsIgnoreCase()。

+0

您不能使用==來比較一個字符串的內容,但有時它會給出與'.equals()'相同的結果。這經常讓新的Java程序員絆倒。如果你寫'String a =「hi」; String b =「hi」;'then'a == b'給出與'a.equals(b)'相同的結果。使用文字設置的測試代碼與==一起工作良好...然後在生產中失敗如果b更改爲'b = new String({'h','i'});'then ==將爲false, a。(b)'仍然是真的; – Paul

0

您正在比較使用==的字符串,這對Object總是一個壞主意。您的空字符串「」指向與t.getDescription()不同的String對象,儘管值可能相同。隨着字符串==有時會工作,因爲字符串類維護一個字符串池,它將用於字符串文字和常量。然而,演示字符串如何工作比文字更好。

public class StringTest 
{ 
    public static void main(String[] args) 
    { 
    String s0=""; // literal 
    System.out.println("Length of s0 = " + s0.length()); 
    System.out.println("Does s0 point to same object as empty string? " 
     + (s0=="")); // since both are literals the same object is used for both 
    System.out.println("Does s0 equal an empty string? " 
     + s0.equals("")); // comparing values 
    System.out.println("Is s0 empty? " + s0.isEmpty()); 
    System.out.println(""); 

    StringBuilder sb = new StringBuilder(""); 
    String s1 = sb.toString(); // don't use a literal for s1 
    System.out.println("Length of s1 = " + s1.length()); 
    System.out.println("Does s1 point to same object as empty string? " 
     + (s1=="")); // s1 is a different object 
    System.out.println("Does s1 equal an empty string? " + s1.equals("")); 
    System.out.println("Is s1 empty? " + s1.isEmpty()); 
    System.out.println(""); 

    // Do this like s1 but with a twist 
    sb = new StringBuilder(""); 
    String s2 = sb.toString(); // again not a literal 
    System.out.println("Does s2 point to same object as empty string? " 
     + (s2=="")); 
    System.out.println("Length of s2 = " + s0.length()); 
    s2 = s2.intern(); // returns the object from the pool that equals() s2 
    System.out.println("Now does s2 point to same object as empty string? " 
     + (s2=="")); // s2 now has the reference to the empty string in the pool 
    System.out.println("Does s2 equal an empty string? " + s2.equals("")); 
    System.out.println("Is s2 empty? " + s2.isEmpty()); 
    } 
} 

我希望這有助於。

+0

真的很有幫助。回答我的問題,也給了我一些關於String類的非常受歡迎的見解。 – derrik

0

另外,您應該在使用.length()之前檢查t.getDescription()。

if(t.getDescription()!=null){ 
(t.getDescription().length()>0)?description.setText(t.getDescription()):description.setVisibility(GONE);} 
else { description.setVisibility(GONE);} 

爲了避免播放字符串,請確保t->描述始終以null開頭,而不是空字符串。這可以在Class構造函數中完成。

0

事實證明,除了直接比較String對象外,還有另一個嚴重的錯誤,我只是想到了。 (請糾正我,如果我錯了。)

因爲在ListView中的視圖有時被回收,「tli」引用有時引用一個視圖誰的可見性屬性已被設置爲「去」。即使字符串不爲空,該屬性也不會變回「可見」。我只需在兩種條件下明確設置該屬性。這裏的固定代碼:

public void setTask(Task t) { 
    task = t; 

    checkbox.setText(task.getName()); 
    checkbox.setChecked(task.isComplete()); 
    if (task.getDescription().equals("")) 
     description.setVisibility(GONE); 
    else 
     description.setVisibility(VISIBLE); 
     description.setText(task.getDescription()); 
} 

它現在的功能是否檢查從task.getDescription()的字符串的內容或長度。

+0

你應該問一個新問題。沒有人會在這裏看到這個Android問題。我對Android開發知之甚少,但知道Java問題的答案。 –

+0

@sjbotha我實際上將問題標記爲Android和Java。這是你的意思嗎?它應該在Android中被問到嗎? – derrik

+0

是的,但是,當您提出一個新問題時,您的問題就會出現在主頁和其他區域。這個問題的文本只會被對您的原始問題感興趣的人閱讀。 –

相關問題