从各种来源学习一些switch
命令教程。我正在尝试基于这个SwitchDemo教程创建一个小程序(我删除了一些重复的代码以节省空间):
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
default: monthString = "Invalid month";
break;
}
System.out.println(monthString);
}
}
在此代码中monthString
不需要在行String monthString;
中初始化。但是,我想使用Scanner
将代码添加到代码中,如下所示:
import java.util.Scanner;
public class App2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int month = scan.nextInt();
String monthString;
switch (month) {
case 1:
monthString = "January";
break;
case 2:
monthString = "February";
break;
case 3:
monthString = "March";
break;
default:
System.out.println("Invalid month");
break;
}
System.out.println(monthString);
}
}
在这种情况下代码不起作用,Eclipse告诉我需要初始化monthString
; eclipse通过将= null
添加到String monthString
来更正它。
这是什么原因?
P.s我是Java的新手,所以你能解释一下,就像你对那些不懂编程的人一样吗?
由于
答案 0 :(得分:3)
这是因为monthString
是一个本地变量,并且您可以在未初始化的路径中使用该路径并且您仍在尝试使用它。
这在Java中是不允许的。我认为原因是Java可以轻松防止您犯错误。它会强迫您确认尚未将monthString
设置为任何内容但您仍然尝试使用它。 10次中有9次,这对开发人员来说是个错误,所以Java不会让你这么做。
解决此问题的一种方法是将monthString
设置为default:
中的内容。你也可以将它初始化为null,正如@Eran所说。
答案 1 :(得分:1)
您可以在声明它时将其初始化为null:
String monthString = null;
或在交换机的default
子句中给它一些默认值。
default:
System.out.println("Invalid month");
monthString = null; // or some other default value
break;
}
如果你不做其中的一个,你可能会在String初始化之前到达System.out.println(monthString);
,这是一个错误。
答案 2 :(得分:0)
基本上,只要你能找到一个语句,就必须初始化该语句中使用的任何变量。
在第二个示例中,default
语句突破了switch
语句,但代码然后在切换后执行下一个语句:System.out.println(monthString)
。因此,变量必须在所有引导它的代码路径中初始化,但它不在default
的情况下。
答案 3 :(得分:0)
其原因在于它是Java语言规范的一部分。如果变量未被"明确分配",则不允许您访问局部变量(或空白的最终字段)的值。编译器执行分析以确保在访问之前进行分配,无论对访问采用何种代码路径。
对于第二个示例,通过默认switch开关的路径永远不会为monthString
赋值,然后在println语句中访问变量的值。
完全确定的分配规则非常复杂。您可以在规范here的第16章中阅读它们。
答案 4 :(得分:0)
或者你可以尝试这样的事情:
String monthString;
switch (month) {
case 1:
monthString = "January";
break;
case 2:
monthString = "February";
break;
case 3:
monthString = "March";
break;
default:
monthString = "Invalid month";
break;
}
System.out.println(monthString);
为了在java中使用局部变量,必须将其初始化为某些东西,即使该东西设置为等于null
。
eclipse正在做的是遵循创建monthString
之间的所有不同路径以及System.out.println(monthString)
中使用它的位置,并确定没有monthString
初始化的位置。
如果你要在封闭的monthString
类中声明SwitchDemo
,那么你的代码也是有效的,因为eclipse无法确定另一种方法是否设置了monthString
。 (如果你这样做,你当然必须将monthString
声明为静态,因为你只能从静态方法中访问静态变量。)