导致java:240的switch语句(可能尚未初始化)

我一直在寻找一个答案,但是没有发现任何真正有助于我的情况如此暴露的事情:

我试图根据输入在变量中存储一个值:

switch(pepperoni) { case 'Y': case 'y': topping1 = 1; break; case 'N': case 'n': topping1 = 0; break; default: { System.out.print("This is not a valid response, please try again \n"); System.out.print("Do you want Pepperoni? (Y/N): "); pepperoni = scan.next().charAt(0); break; } 

我希望变量topping1在输入为’Y’或’y’时存储值1,如果输入为’N’或’n’则存储值0

如果输入既不是’Y’,’y’,’N’也不是’n’,那么我希望它重复该问题,直到输入有效输入为止。

当我稍后在程序中尝试打印值’因为它可能尚未初始化’时出现问题,这有点有意义。 (以下示例)

 if(topping1 > 0) System.out.println("Pepperoni"); // 243: error: variable topping1 might not have been initialized 

我确实知道还有其他方法可以做到这一点,但由于我真的想学习Java,我试图尽可能多地理解基础知识。 因此,如果有人能告诉我为什么这不起作用以及是否有办法通过switch语句或快速修复来实现这一点,我会非常高兴。

如果pepperoni不是YyNn ,则永远不会为topping1 ,因为default情况下从不为其赋值。 例如,如果pepperoni不是这四个值中的一个,那么控制流会跳过其他两种情况并转到default ,这绝不会给topping1一个值,所以稍后当你尝试使用它时, topping1可能从未收到过价值。

“解决方法”是更正逻辑,以便您永远不会尝试使用topping1而不为其赋值。 你如何做到这一点取决于你没有向我们展示的逻辑。 例如,您可以为其分配01以外的值(您在switch的其他分支中分配的值)。

问题可能是switch语句不保证为topping1设置一个值。 如果收到“L”的响应,则不会将其设置为1或0.初始化topping1或在default子句中设置1时,应设置默认值。

Java的编译器无法分析你的代码,知道你不会让人们离开循环(我认为这是在),直到它被设置。 它只能说明代码中有一条路径可以让它不被设置。

这工作(切换也是如此):

 int a; if (condition()) { a=0; } else { a=1; } System.out.println(a); 

这有效:

 int a=1; if (condition()) { a=0; } System.out.println(a); 

这不是:

 int a; if (condition()) { a=0; } System.out.println(a); // compiler error! 

因为如果condition()返回false,则a未定义。 必须定义局部变量。 请注意,这与自动分配默认值null,0或false的类上的字段不同。

您收到“可能尚未初始化”错误,因为您的switch语句中有一条路径,您不会初始化topping1并稍后引用该变量。

你能做什么:将topping1初始化为无效值(比如-1)。 然后将case语句放在while循环中,该循环检查topping1的值是否仍等于-1。

然后,一旦你离开while循环,你知道以下是真的:

  1. 您已初始化topping1 ,因此不会产生编译器错误。
  2. 你有一个有效的topping1值。

这看起来有点难看,但是像这样编写循环是阻止编译器抱怨的一种方法:

 for (;;) { System.out.print("Do you want Pepperoni? (Y/N): "); pepperoni = scan.next().charAt(0); switch (pepperoni) { case 'Y': case 'y': topping1 = 1; break; case 'N': case 'n': topping1 = 0; break; default: System.out.println("This is not a valid response, please try again"); continue; } break; }