public class ABC {
static {
System.out.println(i);
}
static int i=10;
static {
System.out.println(i);
}
public static void main(String[] args)
{
System.out.println(3);
ABC a = new ABC();
}
}
给出错误;
can not reference a field before it is defined
但是跟着 -
public class ABC {
static {
i=20;
System.out.println(ABC.i);
System.out.println(i); //same error as above
}
static int i=10;
static {
System.out.println(i);
}
public static void main(String[] args)
{
System.out.println(3);
ABC a = new ABC();
}
}
不会抛出任何错误并编译并运行正常。即使我使用,
package com.sample.package2;
public class ABC {
static {
System.out.println(ABC.i);
}
static int i=10;
static {
System.out.println("yahan 10" + i);
}
public static void main(String[] args)
{
System.out.println(3);
ABC a = new ABC();
}
}
运行正常。很困惑为什么会出现这个错误。有类似的问题,这听起来可能与你们中的一些人重复,但还没有找到明确的答案。初始化的顺序是什么。我相信静态块先于其他任何东西执行。如果我转移static int i=10;
错误就会消失。静态变量在静态块之前初始化吗?
答案 0 :(得分:0)
你所使用的被称为" 静态初始化块"。如果您已阅读the documentation of initializing fields,您将遇到以下内容(强调我的)
一个类可以有任意数量的静态初始化块,它们可以出现在类体中的任何位置。 运行时系统保证在源代码中按照它们出现的顺序调用静态初始化块。
在您的代码中,您在尝试调用它之后声明并初始化了i
。如果您在静态初始化之前完成了,则不会定义变量i
。
static {
System.out.println(i); // <-- where is i ?
}
static int i=10;
在定义类中的ABC.i
之前使用i
是有效的,因为当您调用ABC
时,正在初始化类ABC
。您必须查看初始化发生的时间。如果您选中JLS 12.4.1,则会注意到
类或接口类型T将在第一次出现以下任何一个之前立即初始化:
...省略... 的
使用T声明的静态字段,该字段不是常量变量
...省略... 的
表示ABC
正在初始化。但是,在初始化期间,static { ... }
方法再次被 调用,因为它使用了一次。在这里,不会抛出错误。因此,可以在ABC.i
方法中调用static { ... }
时检索指定的值,即使在该方法之后已定义i
。
答案 1 :(得分:-1)
static {
System.out.println(i);
}
static int i=10;
您之前正在初始化变量但之前调用它。因此它会抛出错误 wheras
static {
i=20;
System.out.println(i);
}
和
static {
System.out.println(ABC.i);
}
static int i=10;
首先初始化然后调用它。