可以强制执行应用程序中所有文件的静态块吗?

Can one force execution of the static blocks of all the files in the application?

我的目标是让几个 classes 有一个在程序开头运行的代码块。暂时假设 classes 可以随心所欲地添加到项目中,并且在 main.

开头调用静态函数是不切实际的

我已经尝试将初始化例程放在那些 classes 的静态块中,并且它 几乎 按预期工作,但不完全是。只有在 class 中的其他东西被调用后,这些块才会被调用。这可以通过以下代码演示:

Test.java

public class Test
{
    public static void main(String[] args)
    {
        System.out.println("Begin");
        new Another();
    }
}

Another.java

public class Another
{
    static
    {
        System.out.println("Another.static{}");
    }
    public Another()
    {
        System.out.println("Another.Another()");
    }
}

Another2.java

public class Another2
{
    static
    {
        System.out.println("Another2.static{}");
    }
    public Another2()
    {
        System.out.println("Another2.Another2()");
    }
}

输出为:

Begin
Another.static{}
Another.Another()

可以看出Another2假设根本不存在

问题是:是否可以 "kick" 所有 classes 执行它们的静态块(如果它们有)?

你根本做不到。静态块仅在 class 加载程序首次将它们加载到其中时调用。没有其他方法可以给他们打电话。

加载所有保留内容以供以后使用是没有意义的。无论如何,它会在您使用它时执行。

如果 class 由 ClassLoader 加载,则执行静态块。因此,如果您遍历所有 classes 并通过 class 加载程序加载它们(无需实例化它们!),每个静态块将执行一次。

在更深层次上,我无法想象您实际上需要它的情况。这在某种程度上暗示了错误设计的 class 结构。

这是不可能的,因为 VM 永远不会尝试加载自己遍历的代码路径不需要的 class。为什么这样做有一些明显和一些模糊的原因。

经验法则是:如果不存在对从程序入口点可访问(通过代码)的 class 的依赖,那么 class 将 永远不会 被加载。虽然 reachable 很失落,例如只需知道 class' 名称(例如来自配置文件)并使用例如访问该 class 即可建立引用。 Class.forName().

你无法实现的只是将 class 放入 class 路径并让 class 自动成为一个额外的入口点(它执行任何静态代码而没有原因主要(也是唯一)入口点将 class 确定为)。