2010-04-06 82 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