2010-04-06 146 views
1

我想創建一個項目列表,不同的每個我和j變量。我的代碼是:變量無法解析

items cannot be resolved 

我認爲,編譯器認爲該CharSequence[] items可能不會被初始化:

if (i == 0) { 
      if (j == 0) { 
       final CharSequence[] items = {"4:45", "5:00"} 
      } else if (j == 1) { 
       final CharSequence[] items = {"4:43", "4:58"} 
      } else if (j == 2) { 
       final CharSequence[] items = {"4:41", "4:56"} 
      } else { 
       final CharSequence[] items = {"4:38", "4:53"} 
} 

...

new AlertDialog.Builder(this) 
       .setTitle("Hours") 
       .setItems(items, 
       new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialoginterface, int i) { 
         // getStation(i); 
        } 
       }) 
       .show(); 
     } 

我行.setItems(items,得到一個錯誤或者其他什麼... 我怎樣才能讓這個程序運行?

+1

提示:當編譯器認爲它沒有被初始化時,他會告訴你它沒有被初始化。如果它說「無法解決」,那麼這意味着它無法在任何適用範圍內找到該變量。 – 2010-04-06 14:41:56

回答

3

問題在於變量作用域。

if (someCondition) { 
    final int i = 666; 
} else { 
    final int i = 42; 
} 
int j = i + 1; // compile-time error 

這裏,我們有兩個局部變量i誰超出範圍,他們在聲明和初始化之後。如果j需要i的值,那麼i將不得不在更大範圍內進行聲明。

final int i; 
if (someCondition) { 
    i = 666; 
} else { 
    i = 42; 
} 
int j = i + 1; // compiles fine! 

(應該指出的是,這正是那種在三元運營商擅長的方案,即)

final int i = (someCondition) ? 666 : 42; 

在您的具體情況,不幸的是,數組初始化的速記不僅可以用於聲明時初始化。那就是:

int[] arr1 = { 1, 2, 3 }; // compiles fine! 
int[] arr2; 
arr2 = { 4, 5, 6 }; // doesn't compile! 

您可以拉出的items聲明的if外,寫每一個案件(見約阿希姆·紹爾的答案)的冗長的代碼,而是一個更簡潔的代碼是使用數組數組的,而不是。

final CharSequence[][] allItems = { 
    { "4:45", "5:00" }, 
    { "4:43", "4:58" }, 
    { "4:41", "4:56" }, 
    { "4:38", "4:53" } 
}; 
final CharSequence[] items = allItems[j]; 

這種技術以及在這種情況下,但在更一般的情況下,你想使用類似Map什麼的。

注:這是不是在原來的代碼明確,但這個作品,如果j可以是012,或3。如果您想在j0,1,2以外的任何值時申請最後一個選項,那麼您必須在此代碼之前檢查並將其設置爲3

6

您的代碼中實際上有4 items變量,每個變量的作用域都非常有限(僅限於各自的if的代碼塊)。

相反,你需要創建一個變量,一個更大的範圍:

if (i == 0) { 
      final CharSequence[] items; 
      if (j == 0) { 
       items = new CharSequence[] {"4:45", "5:00"}; 
      } else if (j == 1) { 
       items = new CharSequence[] {"4:43", "4:58"}; 
      } else if (j == 2) { 
       items = new CharSequence[] {"4:41", "4:56"}; 
      } else { 
       items = new CharSequence[] {"4:38", "4:53"}; 
      } 
      // you can use items here 
} 

編輯:我忘了new CharSequence[]必要在這裏。如果在聲明期間初始化變量,則可以將其忽略,但在此處將聲明移出並使用簡單分配來設置值。出於某種原因,定義數組的簡短語法是只有在初始化語句(即在與聲明相同的語句中的賦值中)有效。

+1

這實際上不會編譯,會嗎? – 2010-04-06 14:43:47

+0

@Tom:是的,我現在正忙於修復此問題;-) – 2010-04-06 14:44:55

+0

現在這是正確的,但請參閱我的答案,以獲得更加簡潔的替代解決方案,該解決方案在此特定情況下運行良好。 – polygenelubricants 2010-04-06 15:08:20

0

您只是在本地範圍內聲明項目。您需要將if子句外部的if子句移出

final CharSequence[] items 

並在if子句中實例化它。

+0

但是如果變量可以具有不同的類型,那麼在'if'子句中設置呢? – 2014-05-19 17:07:52

1

因爲你在中定義了(以及給出值)items,所以它只在該塊內可見。將定義從塊中拉出到您給我們的片段可見的某個地方,並且ifelse構造內指定值。你現在正在做它之前

if (i == 0) { 

方式

1

申報itemsitems只在裏面你內心if兩方面。

+0

不適用於任何情況,如果變量的類型必須在'if'中設置,該怎麼辦? – 2014-05-19 17:06:11

+0

您仍然可以在if之外定義變量,然後在裏面更改/設置值 – 2017-07-26 23:53:57

2

在Java中,你有嚴格的塊級範圍,因此,例如:

if (blah) { int foo = 1; } 
// foo is no longer visible here 

所以一旦你達到這個右大括號}您的項目變量不再可見。這與JavaScript有所不同,例如您有功能級範圍。

希望這會有所幫助。

+0

ok,但解決方案是什麼?如何在外部獲得變量?我需要創建什麼? – 2014-05-19 17:05:11

+0

您必須在您打算使用它的範圍內聲明該變量。 'int foo = 0; if(blah){foo = 1; } doSomethingWith(foo);' – greim 2014-05-19 23:13:54