【发布时间】:2010-10-15 12:44:17
【问题描述】:
一旦一个类被加载,有没有办法再次调用静态初始化器?
public class Foo {
static {
System.out.println("bar");
}
}
编辑:
我需要调用静态初始化器,因为我没有编写原始类,而我需要调用的逻辑是在静态初始化器中实现的。
【问题讨论】:
标签: java static static-initializer
一旦一个类被加载,有没有办法再次调用静态初始化器?
public class Foo {
static {
System.out.println("bar");
}
}
编辑:
我需要调用静态初始化器,因为我没有编写原始类,而我需要调用的逻辑是在静态初始化器中实现的。
【问题讨论】:
标签: java static static-initializer
将初始化代码放在单独的公共静态方法中,以便您可以从静态初始化程序和其他地方调用它?
【讨论】:
如果类由不同的 ClassLoader 多次加载,则逻辑会多次运行的一种情况。请注意,在这种情况下,它们本质上是不同的类。
不过,一般来说,这些都是一次性交易。如果您希望能够多次调用逻辑,请按照其他人的建议进行操作并将其放入静态方法中。
【讨论】:
我同意 Earwicker 的回答。只需将静态初始化提取到单独的静态方法即可。
public class Foo {
static {
Foo.initialize();
}
public static void initialize() {
System.out.println("bar");
}
}
【讨论】:
如果您真的想要确切问题的确切答案,答案是否定的。无法通过反射调用静态初始化程序或 instanceInitializer。
文档清楚地说:
对于getDeclaredMethod(String name):
如果名称是“
”或“ ”,则会引发 NoSuchMethodException。
对于getDeclaredMethods():
返回的数组中不包含类初始化方法。
所以不,即使通过反射也不可能调用它。
【讨论】:
您可以尝试扩展包含静态代码的类,然后放入您自己的静态初始化程序。不太确定它是否有效,但是:
public class OldBadLibraryClass {
static {
System.out.println("oldBadLibrary static init");
}
}
//next file
public class MyBetterClass extends OldBadLibraryClass {
static {
System.out.println("MyBetterClass init");
}
}
public class Test {
public static void main(String[] args) {
new MyBetterClass();
}
}
看看上面的打印是否按照你期望的顺序。在我的机器上,它工作。
虽然这完全是一个 hack,而且非常脆弱。将旧类修改为具有可以覆盖的 init() 方法确实会好得多。
【讨论】:
https://stackoverflow.com/a/19302726/2300018 是我的帖子,我在其中重新加载了一个实用程序类以重新运行静态初始化程序以进行单元测试。
【讨论】: