Vis*_*l K 30 java static final compilation class-variables
对于以下代码:
public class StaticFinal
{
private final static int i ;
public StaticFinal()
{}
}
Run Code Online (Sandbox Code Playgroud)
我得到编译时错误:
StaticFinal.java:7: variable i might not have been initialized
{}
^
1 error
Run Code Online (Sandbox Code Playgroud)
这符合JLS8.3.1.2,其中说:
如果空白的final(§4.12.4)类变量未被声明它的类的静态初始化程序(第8.7节)明确赋值(第16.8节),则为编译时错误.
所以,完全理解上述错误.
但现在考虑以下内容:
public class StaticFinal
{
private final static int i ;
public StaticFinal()throws InstantiationException
{
throw new InstantiationException("Can't instantiate"); // Don't let the constructor to complete.
}
}
Run Code Online (Sandbox Code Playgroud)
这里,构造函数永远不会完成,因为它InstantiationException是在构造函数的中间抛出的.这段代码编译得很好!!
为什么?为什么这段代码没有显示关于final变量非初始化的编译时错误i?
编辑
我正在使用javac 1.6.0_25命令提示符编译它(不使用任何IDE)
添加 main 方法后使代码打印i。该代码打印值 0。这意味着 java 编译器自动将 i 初始化为值 0。我用 IntelliJ 编写了它,并且必须禁用代码检查才能构建代码。否则它不会让我在抛出异常之前给我同样的错误。
public class StaticFinal {
private final static int i;
public StaticFinal(){
throw new InstantiationError("Can't instantiate!");
}
public static void main(String args[]) {
System.out.print(i);
}
}
Run Code Online (Sandbox Code Playgroud)
完全相同的
public class StaticFinal {
private final static int i = 0;
public StaticFinal(){
throw new InstantiationError("Can't instantiate!");
}
public static void main(String args[]) {
System.out.print(StaticFinal.i);
}
}
Run Code Online (Sandbox Code Playgroud)
public class StaticFinal
{
public StaticFinal()
{
throw new InstantiationError("Can't instantiate!");
}
public static void main(String args[])
{
System.out.print(0);
}
private static final int i = 0;
}
Run Code Online (Sandbox Code Playgroud)
反编译代码后发现事实并非如此。因为反编译后的代码和原来的代码是一模一样的。唯一的另一种可能性是初始化是通过Java虚拟机完成的。我所做的最后更改足以证明情况确实如此。
不得不对你发现这一点说声好。
相关问题: 这里