我有一个这样定义的类:
class MyClass {
private static final String name = "<some string>";
private static final String schema = "{<some json here>}";
public static final MySchemaObject schemaObj = MyUtils.staticSchema(name, schema); // Line1
public static MySchemaObject getStaticSchema() {
return schemaObj;
}
}
另一个类在静态初始化器中调用这个类:
class AnotherClass {
private static final MySchemaObject schemaObject = MyClass.getStaticSchema(); <===== Always null
........
}
在类 AnotherClass
中,静态变量 schemaObject
始终初始化为 null。这表明在调用方法 Line1
时未调用 MyClass 中的 getStaticSchema
。
我的理解是在调用任何静态方法之前创建静态变量,但似乎并非如此。
有人可以帮我理解这个吗?
编辑:MyUtils.staticSchema 永远不会返回 null;
答案 0 :(得分:6)
有两个可能的原因:
MyUtils.staticSchema
返回 null
或AnotherClass
由于循环依赖,在 MyClass
的初始化过程中被初始化。我假设您已经验证/排除了选项 #1,所以我将专注于第二个:
依赖于其他类的非平凡静态字段初始化可能会出现问题,因为它会在类初始化中引入长依赖链甚至依赖循环。
如果 class A
在类初始化期间调用 class B
的方法,而 class B
在类初始化期间调用 class A
的方法,则存在循环:意味着某些代码会看到半初始化的类。
如果您的 MyClass
在类初始化期间以某种方式(直接或间接)接触 AnotherClass
那么很可能对 MyClass.getStaticSchema()
的调用实际上在 before { {1}} 已初始化。
最好的解决方案是让任何类的类初始化依赖于尽可能少的类。
演示问题的简单示例:
schemaObj
如果您尝试打印 class A {
public static final String CONSTANT_IN_A = B.CONSTANT_IN_B;
public static final String ANOTHER_VALUE = "Value " + (Math.random() * 0 + 1);
}
class B {
public static final String CONSTANT_IN_B = "B version of " + A.ANOTHER_VALUE;
}
,输出将是 A.CONSTANT_IN_A
,因为在 B version of null
的初始化过程中,B.CONSTANT_IN_B
中的字段 ANOTHER_VALUE
还没有已初始化。