Java 局部变量初始化
为什么编译器很高兴变量Java 局部变量初始化,java,Java,为什么编译器很高兴变量g在if(true)语句中初始化,而在if(gg)案例中抱怨g初始化,抛出以下错误: 错误:(11,28)java:变量g可能未初始化 public static void main(String args[]) { boolean gg = true; int g; if (gg) // if (true) { g = 6; } System.out.println(g); } true是一个
g
在if(true)
语句中初始化,而在if(gg)
案例中抱怨g
初始化,抛出以下错误:
错误:(11,28)java:变量g可能未初始化
public static void main(String args[]) {
boolean gg = true;
int g;
if (gg)
// if (true)
{
g = 6;
}
System.out.println(g);
}
true
是一个常量表达式,编译器可以在编译时扣除它的值
另一方面,gg
不是常数,而是一个变量,您可以用任何东西(甚至是表达式、函数返回值等)初始化它。因此,编译器不会检查您是如何初始化该变量的,而是假定它可以是任何变量
这就是为什么编译器认为变量g
可以初始化,也不能初始化的原因
你认为编译器能深入到什么程度?以这个为例:
boolean gg = Math.random() >= 0.5;
gg = gg ? gg : true;
boolean gg = (Math.random() >= 0.0);
我们知道gg
是真的,但是编译器是怎么知道的呢
或者另一个例子:
boolean gg = Math.random() >= 0.5;
gg = gg ? gg : true;
boolean gg = (Math.random() >= 0.0);
同样,我们知道它总是正确的(因为random()
介于0.0
和1.0
之间),但编译器不知道
因此,对于编译器来说,这不是一项容易的任务,因此编译器创建者决定在预测执行流时只检查常量表达式,而不是猜测变量值
这就是为什么在一种情况下会收到警告,而在另一种情况下不会收到警告。true
是一个常量表达式,编译器可以在编译时扣除它的值
另一方面,gg
不是常数,而是一个变量,您可以用任何东西(甚至是表达式、函数返回值等)初始化它。因此,编译器不会检查您是如何初始化该变量的,而是假定它可以是任何变量
这就是为什么编译器认为变量g
可以初始化,也不能初始化的原因
你认为编译器能深入到什么程度?以这个为例:
boolean gg = Math.random() >= 0.5;
gg = gg ? gg : true;
boolean gg = (Math.random() >= 0.0);
我们知道gg
是真的,但是编译器是怎么知道的呢
或者另一个例子:
boolean gg = Math.random() >= 0.5;
gg = gg ? gg : true;
boolean gg = (Math.random() >= 0.0);
同样,我们知道它总是正确的(因为random()
介于0.0
和1.0
之间),但编译器不知道
因此,对于编译器来说,这不是一项容易的任务,因此编译器创建者决定在预测执行流时只检查常量表达式,而不是猜测变量值
这就是为什么在一种情况下会收到警告,而在另一种情况下不会收到警告。这是由于声明和初始化之间的差异
等号前面的部分是声明boolean gg
或int g
,初始化是=true
在上述情况下,gg
始终被初始化,但只有当gg
为真时,g
才被初始化。只有通过运行代码来确定gg
的值才能知道这一点(我们可以通过手动运行代码来判断这是真的),因此我们收到编译器的投诉g
变量可能没有初始化。这是由于声明和初始化之间的差异造成的
等号前面的部分是声明boolean gg
或int g
,初始化是=true
在上述情况下,gg
始终被初始化,但只有当gg
为真时,g
才被初始化。只有通过运行代码来确定gg
的值才能知道这一点(我们可以通过手动运行代码来判断这是真的),因此我们收到编译器的投诉g
变量可能没有初始化。编译器很可能会将if(true)
条件优化为无条件(尝试反编译.class,如果
块消失,您应该会看到)
然而,即使是局部变量引用,在上下文中也没有可能的更改,这一点也不是那么可以预见的,因此它不会对此进行“优化”,这表明它不会预测您的条件将始终是真的
因此,它留给您一个仅在某个条件下初始化的局部变量(不管该条件仅在运行时在这个特定上下文中是多么真实),并在稍后由println
调用引用,其“风险”是没有实际初始化
这反过来会导致“急切”编译器错误。编译器很可能会将if(true)
条件优化为完全没有条件(尝试反编译.class,您应该会看到if
块消失)
然而,即使是局部变量引用,在上下文中也没有可能的更改,这一点也不是那么可以预见的,因此它不会对此进行“优化”,这表明它不会预测您的条件将始终是真的
因此,它留给您一个仅在某个条件下初始化的局部变量(不管该条件仅在运行时在这个特定上下文中是多么真实),并在稍后由println
调用引用,其“风险”是没有实际初始化
这反过来又会导致“渴望”编译器错误。gg
不是编译时常量,因此编译器不知道gg
是否为true
。确定g
是否在print
语句中明确指定的规则有很好的文档记录,并且占用了整个章节。编译器无法确保gg始终为true(它可以在代码中的某个地方重新赋值),Site中有两个答案,因为编译器没有保留状态,因此它知道gg是否总是为真。它看到您有一个布尔值,在某些情况下它可能为假(否则为什么会有if语句?)。如果gg为假,则g将为非