【问题标题】:Variable cannot be resolved变量无法解析
【发布时间】:2010-04-06 14:37:32
【问题描述】:

我正在尝试创建一个项目列表,每个 i 和 j 变量都不同。我的代码是:

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, 行中收到错误:

items cannot be resolved

我认为编译器认为CharSequence[] items 可能没有被初始化或者什么的...... 我怎样才能让这个程序运行?

【问题讨论】:

  • 提示:当编译器认为它没有被初始化时,他会告诉你它没有被初始化。如果它说“无法解析”,则意味着它无法在任何适用范围内找到该变量。

标签: java android


【解决方案1】:

您的代码中实际上有 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[] 在这里是必需的。如果您在声明期间初始化变量,则可以将其省略,但在这里您将声明移出并使用简单的赋值来设置值。出于某种原因,定义数组的简短语法在初始化语句中有效(即,在与声明在同一语句中的赋值中)。

【讨论】:

  • 这现在是正确的,但请参阅我的答案以获得更简洁的替代解决方案,该解决方案在这种特殊情况下效果很好。
【解决方案2】:

问题在于变量范围。

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!

您可以在 if 之外提取 items 的声明并为每种情况编写详细代码(请参阅 Joachim Sauer 的回答),但更简洁的代码是使用数组数组代替。

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 可以是0123,则此方法有效。如果您希望在j 是除012 之外的任何值时应用最后一个选项,那么您必须在此代码之前检查并设置为3

【讨论】:

    【解决方案3】:

    在 Java 中,您有严格的块级范围,例如:

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

    所以一旦你到达那个右花括号 },你的 items 变量就不再可见了。这与 JavaScript 不同,例如您具有函数级范围。

    希望这会有所帮助。

    【讨论】:

    • 好的,但是解决方案是什么?,我怎样才能在外面得到一个变量?我需要创建什么?
    • 您必须在您打算使用它的范围内声明该变量。 int foo = 0; if (blah) { foo = 1; } doSomethingWith(foo);
    【解决方案4】:

    因为您在一个块内定义(并为其赋值)items,所以它仅在该块内可见。将定义从块中拉出到您给我们的 sn-ps 可见的某个地方,然后在 if else 构造中分配一个值

    【讨论】:

      【解决方案5】:

      之前声明items
      if (i == 0) {
      

      你现在的做法,items 只在你内部ifs 的范围内。

      【讨论】:

      • 并不适用于所有情况,如果必须在if 中设置变量的类型怎么办?
      • 您仍然可以在 if 之外定义变量,然后在内部更改/设置值
      【解决方案6】:

      您只是在本地范围内声明项目。你需要移动

      final CharSequence[] items
      

      在 if 子句之外,在 if 子句中实例化它。

      【讨论】:

      • 但是如果变量可以有不同的类型,在if 子句中设置呢?
      猜你喜欢
      • 1970-01-01
      • 2012-04-14
      • 1970-01-01
      • 2020-01-17
      • 2021-12-17
      • 2018-10-28
      • 2011-11-27
      • 2021-12-21
      相关资源
      最近更新 更多