public class Test1 {
static final int i;
static{
if(3<2){
i = 0;
}
}
}public class Test2 {
static final int i;
static{
if(3>2){
i = 0;
}
}
}类Test1编译失败,类Test2编译成功。
有人能告诉我编译器是如何在if条件下计算表达式的吗?
发布于 2012-12-09 18:00:34
static final int i;需要在静态初始化器中初始化,因为它是最终的。
static{
if(3<2){
i = 0;
}
}由于3<2文字或常量,编译器能够检测到代码的无效部分,并且不会初始化i。
添加一个else用例并在其中执行一些i初始化。
发布于 2012-12-09 18:06:28
它与编译器如何确定语句是否将被执行有关。它是在JLS #16中定义的
每个局部变量和每个空的最终字段在其值发生任何访问时都必须有一个明确分配的值。
在您的示例中,编译器可以确定在编译时是否明确分配了i,因为if中的表达式是常量表达式。
JLS #15.28定义常量表达式
编译时常量表达式是表示基元类型的值或字符串的表达式,该表达式不会突然完成,并且仅使用以下内容组成:
有趣的是,尽管Test2可以编译,但这个修改后的Test2版本不能编译:
static class Test3 {
static final int i;
static {
int j = 3;
if (j > 2) {
i = 0;
}
}
}原因是j > 2不再是一个常量表达式。将j设为final会使这个类再次编译。
发布于 2012-12-09 18:08:49
根据Java Language Specification的说法,if语句的条件部分中的表达式是编译时表达式。在Test1编译器知道我永远不会被初始化,这就是为什么它会报错。在第二种情况下,编译器知道我将被初始化。如果将编译时表达式替换为更动态的表达式,两个类都将无法编译,因为编译器不能保证我已被初始化。
https://stackoverflow.com/questions/13786424
复制相似问题