Java 为什么变量出现在循环中而不出现在循环外?

Java 为什么变量出现在循环中而不出现在循环外?,java,initialization,compiler-errors,Java,Initialization,Compiler Errors,我有以下代码: String serviceType; ServiceBrowser tmpBrowser; for (String playerName: players) { serviceType = "_" + playerName + "._tcp"; tmpBrowser = BrowsersGenerator.getBrowser(serviceType); tmpBrowser.browse();

我有以下代码:

    String serviceType;
    ServiceBrowser tmpBrowser;
    for (String playerName: players) {
        serviceType = "_" + playerName + "._tcp";
        tmpBrowser = BrowsersGenerator.getBrowser(serviceType);
        tmpBrowser.browse();
        System.out.println(tmpBrowser.getStatus());
    }       
    System.out.println(tmpBrowser.getStatus());

编译器抱怨最后一行。它写到“变量tmpBrowser可能未初始化”。如果我对最后一行进行注释,编译不会抱怨。

如果
players
变量中的元素数为零,则循环将不会执行,因此执行
System.out.println()
调用时,
tmpBrowser
变量将永远不会初始化(甚至不会初始化
null
值)


解决此错误的唯一方法是为tmpBrowser变量提供一个有意义的默认值(即使只有
null
,但如果无法摆脱上一个
System.out.println(tmpBrowser.getStatus()
),那么仍然会有
null点异常由
tmpBrowser.getStatus()引发)呼叫。

如果没有
播放器
,则
tmpBrowser
将不会以任何方式初始化。编译器无法预测是否有玩家。此外,与字段(在方法块外部声明的类/实例变量)相反,局部变量(在方法块内部声明的)不会用默认值预先初始化。您需要自己对编译器进行预初始化,以使编译器满意:

ServiceBrowser tmpBrowser = null;

(在
getStatus()
之前不要忘记执行空检查,否则您可能会面临NPE的风险)。

因为如果玩家是空集合,它实际上可能尚未初始化。

如果您从未输入for循环,例如当
玩家
数组为空时,变量
tempBrowser
将保持未初始化状态。因此,要克服这一问题,您需要确保
tempBrowser
具有一个分配给它的值,而与循环无关。比如:

ServiceBrowser tmpBrowser = null;

之前,循环将有帮助。

它不会为空。它将保持未初始化状态。这就是它无法编译的原因。@BalusC:我不理解你的评论。来自wikipedia:在Java中,没有显式初始值设定项和数组元素的类和对象的字段会自动初始化为其类型的默认值(布尔值为false,所有数值类型为0,所有引用类型为null)。Java中的局部变量在被访问之前必须被明确地赋值,否则这是一个编译错误。@BalusC当然,代码不会实际运行,因此会出现编译错误,但如果要运行,tmpBrowser变量的值可能为null(任何未初始化变量的值),因此出现了编译器错误。@LB和Peter Nix:您将字段与局部变量混淆了。好的,我想我误解了“没有显式初始值设定项的对象”。(我不会混淆字段和局部变量..真的..:-))。