为什么这个本地变量在Java中没有初始化?

3

我正在学习Java,我知道在使用局部变量时必须对其进行初始化。但是,我在一本书中发现了如下代码:

int volume;
if (someCondition) {
    volume = 10;
}

我想知道为什么在这种情况下变量volume没有被初始化?

public static double cubeVolume(double sideLength)
{
    double volume;
    if (sideLength>=0)
    {
        volume=sideLength*sideLength*sideLength;
    }
    else
   {
      volume=0;
   }
   return volume;
}

返回 sideLength>=0?(sideLengthsideLengthsideLength):0; 这样处理这种情况会更酷 :P - Faisal Ali
变量volume将始终在ifelse中被赋值。因此不需要显式初始化。 - Omoro
1
阅读有关声明、初始化和在声明时初始化之间的区别。 - Sotirios Delimanolis
3个回答

6
规则是必须在使用之前初始化,因为在if语句的两个分支上都已经初始化了volume,所以编译器可以保证在使用之前它已经被初始化。
如果你在if语句之前尝试使用volume,你将再次收到编译错误。同样地,如果没有在所有分支(在这种情况下是if语句的两侧)上初始化,你会得到一个错误。
示例
以下示例可能会说明这什么时候可能会成为问题:
好的(但无意义):
double volume; //<--declared
volume=6;  //<--initialised
double volumeUsed=2*volume;

好的:

boolean useUpper=true; //<-- useUpper declared and initialised
double volume;
if (useUpper){
    volume=6; //<--initialised
}else{
    volume=7; //<--initialised
}
double volumeUsed=2*volume;

不可行(使用时未知音量):

double volume;
double volumeUsed=2*volume;

不好(当useUpper为false时,volume可能未知):

boolean useUpper=true;
double volume;
if (useUpper){
    volume=6; //<--initialised
}
//volume may not be initialised
double volumeUsed=2*volume;

不行:在初始化之前使用

double volume;
double volumeUsed=2*volume;
if (sideLength>=0)
{
    volume=sideLength*sideLength*sideLength; //<--initialised (too late)
}
else
{
   volume=0;
}
return volume;

那为什么不在 double volume; 处进行初始化呢? - djechlin
哦,特别是如果您搞砸了第二个else块,您可以强制编译错误。 如果您添加上述内容,我会点赞。 - djechlin
@djechlin,示例4是否涵盖了此内容? - Richard Tingle
@user3504084 这是否使用 variable++?这相当于 variable=variable+1,这又是在 variable 被初始化(即设置为具有值)之前使用 variable - Richard Tingle
我明白了。现在我清楚如何初始化变量了。感谢您的出色解释! - user3504084
显示剩余2条评论

1
因为在评估if之前,作者对volume没有任何价值。
其他选项包括:
double volume = 16.0; // Random. Wrong. Bug-prone.

或者:

double volume = 0.0; // Conveys that 0 is somehow a valid value. 
// or that another value might not be entered.

当然,在这种情况下,0.0是一个完全有效的值,因此这个选项是可以的:
double volume = 0.0;
if(sideLength >= 0) {
    volume = sideLength * sideLength * sideLength;
}

但这也引出了一个问题:为什么我们设置了两次 volume?我认为这不是什么大问题,但有些程序员可能会不喜欢它。现在问题变得更加复杂了,如果 volume 需要带上 final 修饰符,例如在稍后的闭包中使用了它,那么这将是非法的:
final double volume = 0.0;
if(sideLength >= 0) {
    volume = sideLength * sideLength * sideLength;  // compiler error
}

如果作者偏爱简洁(我在这里不建议这样做),那么可以用以下一行完成所有操作:
double volume = sideLength >=0 ? sideLength * sideLength * sideLength : 0;

还有一个更聪明的例子(这很糟糕,请不要这样做):

double volume = Math.max(sideLength * sideLength * sideLength, 0);
// does not generalize to even dimensions

-2

不要那样做,改为这样:

public static double cubeVolume(double sideLength)
{
    double volume = 0;
    if (sideLength>=0)
    {
        volume=sideLength*sideLength*sideLength;
    }
   return volume;
}

1
问题不在于纠正代码,而在于为什么书中的示例代码没有初始化本地变量。 - Abdullah Shoaib
因为在if语句被评估之前,写入者对于volume没有任何值。 - ASKASK
从下面的回答可以看出,基本上解释了为什么。 - ASKASK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接