【问题标题】:Java: Error: variable might not have been initializedJava:错误:变量可能尚未初始化
【发布时间】:2014-06-10 23:15:59
【问题描述】:

我正在学习 Java,但遇到此错误。我知道这已被问过几次(很多次),但似乎没有一个答案能回答我的问题。代码主体为:

String[] number = {"too small", "one", "two", "three", "four", "too large"};
int i;
if(num<1){
    i=0;
}
if(num==1){
    i=1;
}
if(num==2){
    i=2;
}
if(num==3){
    i=3;
}
if(num==4){
    i=4;
}
if(num>4){
    i=5;
}
return number[i];

变量 'num' 是在前面声明、初始化和给出的。 我得到的错误是:“变量 'i' 可能没有被初始化”并指向最后一行(返回 number[i];)。

问题是,如果我声明 'i' 并立即分配一个值 (int i=0;),则代码运行良好。但是,如果我没有分配一个值,即使在每个“if”之后分配了一个可能的值,我也会得到错误。

例如,我不会在 C 语言中遇到这种错误。

谢谢

【问题讨论】:

  • 编译器告诉你它希望你赋值;显然,当您这样做时,它将起作用。你为什么不想这样做?
  • rgettman 很好地解释了这一点。我首选的解决方法是 (1) 在所有分支上使用 else,并且 (2) 将最后一个设置为 else 而没有另一个 if,即 else { ... 而不是 else if (num &gt; 4) { ...。我认为这让读者更清楚,也避免了“明确的分配”问题。在这种特殊情况下,我只写int i = (num &lt; 1) ? 0 : (num &gt; 4) ? 5 : num;
  • @ajb 三元分生孢子在这里似乎太复杂了。我只是一个else :|
  • @JeroenVannevel 它确实有效,但我想知道为什么它在其他方面无效。
  • This chapter of the jls 定义了明确分配的规则。

标签: java


【解决方案1】:

Java 不会分析您的 if 块的逻辑以确定您的 if 语句之一将运行并将值分配给 i。这很简单,它看到了没有if 语句运行的可能性。在这种情况下,i 在使用之前不会分配任何值。

Java 不会为局部变量提供默认值,即使它为类变量和实例变量提供默认值也是如此。 Section 4.12.5 of the JLS 涵盖了这个:

程序中的每个变量在使用它的值之前都必须有一个值:

局部变量(第 14.4 节、第 14.14 节)必须在使用前通过初始化(第 14.4 节)或赋值(第 15.26 节)显式地赋予一个值

i 分配某种默认值,当您声明它时,以满足编译器的要求。

int i = 0;
// Your if statements are here.
return number[i];

【讨论】:

  • 我不建议在大多数情况下使用默认分配,因为我发现它可以隐藏问题 - 即忘记处理一些逻辑。相反,我通常使用适当的else,它更明确、更明确(例如,正确的解决方案也可能是提前返回或抛出异常)。
  • @user2864740 在这种情况下我同意你的看法。但是,我遇到了涉及循环的情况,在这些情况下,我可以知道在循环退出之前总是会分配一个变量,但是没有很好的方法来重新排列代码以使编译器相信这一点。我确实看到你说的是“大多数情况”。
  • @user2864740 我认为这两种方法都是有效的。我使用了任何一种方式(默认显式初始值加上简单的 else),这取决于在这种情况下哪种方式更易读、更清晰。
  • @rgettman 奇怪的是,当我将 'else if(...)' 用于 2-4 和 else{...} 用于 5 时,代码有效,而没有初始化变量 'i'开始。就像 Java 不假设所有可能性都包含在多个“if”中,但它理解所有可能性都包含在一个“if”和多个“else”中。
  • @rgettman 我并不是要说默认分配无论如何都是错误的(这个答案肯定是正确的)——这不是我修复这个编译器错误的“去处”。跨度>
【解决方案2】:

如果你想清理代码,你可以很容易地做到这一点:

String[] number = {"too small", "one", "two", "three", "four", "too large"};
int i = num;
if (i < 1) { i = 0; }
if (i > 4) { i = 5; }
return number[i];

或者如果num 的值甚至无关紧要:

String[] number = {"too small", "one", "two", "three", "four", "too large"};
if (num < 1) { num = 0; }
if (num > 4) { num = 5; }
return number[num];

即使您之前的代码在逻辑上看起来没问题,编译器也无法始终与人类智能竞争。给它这个默认值将有助于满足你的方法的安全性。

【讨论】:

    猜你喜欢
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多