我有一个静态类,如下所示:
public class StaticClass {
public static final String stringValue;
static {
stringValue = OtherClass.someMethod();
}
}
我们在整个地方使用StaticClass.stringValue
。但是在给定的情况下,我想强制它重新加载,所以静态初始化程序再次运行。
这可能吗?
我知道我可以使用反射手动设置此字段。但实际上,这个类中有1000个字段。
我完全清楚这听起来多么奇怪,为什么我不应该这样做。我想知道这是否可行。我希望该字段是最终的,因此我的开发人员不会意外地更改值。但我希望在给定的用户输入后,所有字段都重新加载。
答案 0 :(得分:1)
ClassLoader每个类只运行一次静态初始值设定项(因为类被加载到内存中)。
如果你想将静态字符串保持为final
,我能看到的唯一方法就是使用自定义类加载器(或者通过ASM使用一些字节代码魔法)。
如果丢弃类加载器并使用新的类加载器再次加载类,静态块将再次运行。
请注意,这可能会导致问题,因为旧类不等于新类。引用静态最终字段的所有对象也需要重新加载。
这听起来很混乱,而且有很糟糕的设计气味。
答案 1 :(得分:0)
您可以将初始化代码重构为一个方法,该方法在静态初始化程序块中调用,并且还会在以后再次调用。
为了完整性:可以通过使用ClassLoader强制重新加载类并因此重新初始化 - 例如此tutorial。虽然技术上可行,但这不太可能是解决问题的好方法。
答案 2 :(得分:0)
如果你想要的是保持一个stringValue
不能是OtherClass.someMethod()
以外的关系,为什么不使用一个获取它的getter方法来代替甚至维护一个变量?
喜欢的东西:
public class StaticClass {
public static getStringValue()
{
return OtherClass.someMethod();
}
}
我认为我们需要更多关于这个问题的信息。可能有更好的方法来做你想做的事。
答案 3 :(得分:0)
简单的解决方案=删除stringValue声明之前的最后一个单词并执行此操作。
public static void staticValueInitialisation() {
stringValue = OtherClass.someMethod();
}
答案 4 :(得分:0)
Java有这种东西的访问修饰符。看起来你希望开发人员能够在不改变它的情况下访问该值,这就是公共(静态)getter的用途。您可以将该字段设为私有但不是最终字段,并使其他代码重新加载或执行您想要的任何其他类型的修改。