我在两个不同的文件中有两个类,每个文件都有一个静态变量,我想知道是否有一种方法可以预测哪个将首先被初始化(是否依赖于实现)?我的代码看起来像这样?
File1:
public class A
{
public static boolean a = Logger.log();
}
File2:
public class B
{
public static boolean b = Logger.log();
}
File3:
public class Logger
{
public static boolean log();
}
答案 0 :(得分:8)
这取决于每个班级首次使用。
来自section 12.4.1 of the Java Language Specification:
JLS的类或接口类型T将在第一次出现以下任何一个之前立即初始化:
T是一个类,并创建了一个T实例。
T是一个类,调用T声明的静态方法。
分配由T声明的静态字段。
使用T声明的静态字段,该字段不是常量变量(§4.12.4)。
T是顶级类(第7.6节),并且执行在词典中嵌套在T(第8.1.3节)内的断言语句(第14.10节)。
对静态字段的引用(第8.3.1.1节)仅导致实际声明它的类或接口的初始化,即使它可能通过子类的名称,子接口或实现的类来引用界面。
Section 12.4.2详细指定了初始化过程。
老实说,如果您的代码要求在另一个之前进行初始化,尽管没有明显的依赖性,那么无论如何您都会遇到问题。
答案 1 :(得分:0)
JVM不会保留所有类的记录,但是当请求类或类的静态成员时,它会从内存中加载类。所以遵循的实际过程是这样的:
第一次要求上课时:
所有静态变量
静态区块(按顺序排列,先是第一个,然后是第二个,依此类推)
实例变量(成员)
初始化程序块(按顺序)
构造
第二次或之后:
所有实例变量(成员)
初始化程序块(按订单)
构造
我希望这会对你有所帮助。
...谢谢
Mr.777
答案 2 :(得分:0)
根据你的例子 - 在A.a之前无法初始化B.b,因为B类的访问将首先调用其supper类的静态初始化。
如果你真的需要在B之前做一个逻辑 - 尝试将它封装在静态方法中:
public class A
{
public static boolean a;
public static init() {
a = log();
}
}
public class B
{
public static boolean b;
public static init() {
b = log();
}
}
public class Main
{
public static void main(String[] args) {
B.init();
A.init();
}
}