简化代码时发生Java开关错误

简化代码时发生Java开关错误,java,switch-statement,Java,Switch Statement,大家好,这是我的第一篇帖子,如果我犯了任何错误,请原谅我。 我的问题是: public class Main { public static void main(String[] args) { int onlineplayer = 0; int maxplayer; switch(onlineplayer) { case 0: maxplayer = 1; break; case 1: ma

大家好,这是我的第一篇帖子,如果我犯了任何错误,请原谅我。 我的问题是:

public class Main {
public static void main(String[] args) {
    int onlineplayer = 0;
    int maxplayer;
    switch(onlineplayer) {
        case 0:
        maxplayer = 1;
        break;
        case 1:
        maxplayer = 2;
        break;
    }
    System.out.print(onlineplayer + "/" + maxplayer);
}
这行代码返回以下错误:

Main.java:13: error: variable maxplayer might not have been initialized
    System.out.print(onlineplayer + "/" + maxplayer);
                                          ^

这个有效。
我刚才说过学习Java,我认为它们是一样的。有人能给我解释一下区别是什么,为什么第一个不起作用?

代码看起来可能类似,但区别如下:

在第二个示例中,
print
函数是在设置
maxplayer
后直接调用的,因此在读取变量时,可以保证对其进行设置

但在第一个示例中,开关不能保证输入任何情况,因此当到达
print
行时,
maxplayer
仍可能未初始化

为了防止出现这种情况,您通常会添加一个
默认值
案例,如果没有其他案例匹配,则会执行该案例。这样可以保证设置了
maxplayer

switch(onlineplayer) {
    case 0:
        maxplayer = 1;
        break;
    case 1:
        maxplayer = 2;
        break;
    default:
        System.out.print("Some warning");
        maxplayer = 1; // some default value
}

请记住,您的交换机中应该始终有一个
默认值
机箱!请参阅以下关于为什么
默认值
案例很重要的好解释:

因为编译器不够“智能”

在您的第一个代码剪接集中,如果
onlineplayer
的值不同于0或1,则
maxplayer
将保持未初始化状态。
当然,这实际上是不可能的,因为
onlineplayer
是用值0初始化的,没有其他线程可以修改它。但编译器无法识别这一点


这种“聪明”的缺乏实际上是根据设计。Java语言规范有明确赋值的规则,您可以在

处阅读。注意:如果您认为
default
分支不可能,您可以只编写
default:throw new AssertionError()
没有将任何值设置为
maxplayer
。您提到了一个要点!任何人都不应该只接受这段代码片段,并遵循其中的实践。它始终取决于应用程序如何处理默认情况。我想,一个好的开始总是问自己,如果你在默认情况下着陆,对程序来说有多糟糕。
switch(onlineplayer) {
    case 0:
        maxplayer = 1;
        break;
    case 1:
        maxplayer = 2;
        break;
    default:
        System.out.print("Some warning");
        maxplayer = 1; // some default value
}