class Foo{
public static void main(String args[]){
final int x=101;
int y;
if(x>100){
y=-1;
}
System.out.println(y);
}
}
Java编译器了解if语句的条件始终为true,因此y将始终被初始化。没有编译错误,如预期的那样。
class Bar{
public static void main(String args[]){
final int x;
x=101;
int y;
if(x>100){
y=-1;
}
System.out.println(y);
}
}
但是,当我将x的声明和初始化分为两行时,编译器似乎没有得到条件始终为true且y将始终被初始化的信息。
final int x;
x=101;
byte b;
b=x;
System.out.println(b);
同样的事情在这里发生,编译器会损失精度误差。
final int x=101;
byte b;
b=x;
System.out.println(b);
同样,编译器可以理解x在b的范围内。
它与编译器如何确定是否执行语句有关。它在JLS#16中定义:
每个局部变量和每个空白的final字段在对其值进行任何访问时都必须具有一个明确分配的值。
在您的情况下,编译器无法确定y
已被明确分配,并给您一个错误。这是因为它将需要确定条件始终为真,并且仅当中的条件if
为 常量表达式时 才有可能。
JLS#15.28定义
常量表达式 :
编译时常量表达式是表示原始类型或String的值的表达式,该值不会突然完成,并且仅使用以下内容组成:
- […]
- 引用常量变量(第4.12.4节)的简单名称(第6.6.5.6.1节)。
该JLS#4.12.4定义
常量变量 为:
最终类型并使用编译时常量表达式初始化的基本类型或String类型的变量称为常量变量。
在您的情况下,final int x = 101;
是一个常量变量,但final int x; x = 101;
不是。
Java编译器知道if语句的条件总是true,因此y总是被初始化的。正如预期的那样,没有编译错误。 但是当我把x的声明和初始化分成两行时,编译器似乎没有得到条件总是真的,y总是被初始化的。 这里也会发生同样的情况,编译器会给出精度损失错误。 同样,编译器可以理解x在b的范围内。
问题内容: Java的设计者是否有任何理由认为不应为局部变量提供默认值?认真地讲,如果实例变量可以被赋予默认值,那为什么我们不能对局部变量做同样的事情呢? 问题答案: 声明局部变量主要是为了进行一些计算。因此,程序员决定设置变量的值,并且不应采用默认值。如果程序员错误地没有初始化局部变量并且使用默认值,则输出可能是一些意外值。因此,在使用局部变量的情况下,编译器将要求程序员在访问变量之前使用一些值
问题内容: 我已经搜索了很多,并在此处给出的堆栈溢出中得到了这个答案 那说明我们可以同时使用构造函数和简单初始化 但我想要答案 但是,如果编译器自动完成构造函数初始化,为什么还要使用构造函数初始化呢! 问题答案: 构造函数的简单定义: 初始化类对象的特殊方法。始终且仅与关键字一起使用以创建类的实例。 与类的名称相同。 可以接受一个或多个参数。 没有返回值,甚至没有void。 默认构造函数不带任何参
问题内容: print语句导致以下编译时错误, 局部变量f可能尚未初始化 如果Java中的原语已经具有默认值(float = 0.0f) ,为什么需要定义一个? 所以这有效 感谢大家! 问题答案: 因为它是一个局部变量。这就是为什么什么都没有分配的原因: 局部变量略有不同。编译器永远不会为未初始化的局部变量分配默认值。如果您无法在声明它的地方初始化本地变量,请确保在尝试使用它之前为其分配一个值。访
print语句会导致以下编译时错误, 局部变量f可能尚未初始化 如果Java中的原语已经有一个默认值(float=0.0f),为什么我需要定义一个呢? 所以,这是有效的 谢谢大家!
(这个问题与此密切相关,但它是一个更具体的问题,我希望能就此得到答案)