4

我的目标是有几个类有一个在程序开始时运行的代码块。假设可以一时兴起将类添加到项目中,并且在main.

我试图将初始化例程放在这些类的静态块中,它几乎可以按预期工作,但并不完全。只有在该类中的其他内容被调用后,这些块才会被调用。这可以通过下面的代码来证明:

测试.java

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

另一个.java

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

另一个2.java

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

输出是:

Begin
Another.static{}
Another.Another()

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

问题是:是否有可能“踢”所有类来执行它们的静态块(如果它们有它们)?

4

3 回答 3

11

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

在更深层次上,我无法想象你真正需要这个的情况。这在某种程度上暗示了错误设计的类结构。

于 2015-10-26T11:13:46.997 回答
2

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

经验法则是:如果从程序入口点(通过代码)可访问的类不存在依赖关系,则永远不会加载该类。尽管reachable是相当丢失的,例如可以通过只知道一个类的名称(例如从配置文件)并使用例如Class.forName() 访问该类来建立引用。

您无法实现的只是将一个类放入类路径并让该类自动成为一个额外的入口点(执行任何静态代码而没有来自主(也是唯一)入口点的原因将归类为)。

于 2015-10-26T13:27:31.697 回答
1

简直不能。静态块仅在类加载器第一次加载它们时调用。没有其他方法可以打电话给他们。

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

于 2015-10-26T11:13:22.800 回答