Java中的全局代码初始化



因为JVM是按需加载类和代码的,所以没有办法在一些随机的类(除了包含main()函数的类)中拥有初始化代码,并让它在JVM启动时运行。我知道这种想法与JVM的设计背道而驰。然而,有时你想做这样的事情,我很好奇是否有一些"标准"的方式来做,除了有一个长,集中的初始化函数列表的函数调用某处,并从main()函数调用它们。

我想知道的具体原因是因为我有一个带有GUI系统的程序。这个程序连接到一个服务器,它的行为有点像一个图形终端,允许服务器创建与用户交互的小部件。为了做到这一点,小部件需要具有某种类型的ID,服务器可以使用该ID通过协议引用它们,并且需要有某种类型的此类ID注册表。现在,我正在使用这些id的全局映射,映射到WidgetFactory类的实例,并且我正在基本Widget类中的静态{}块中初始化这些id,类似于:

public class Widget {
    private final static Map<String, WidgetFactory> widgets = new HashMap<String, WidgetFactory();
    static {
        widgets.put("wnd", Window.factory);
        widgets.put("lbl", Label.factory);
        widgets.put("text", TextEntry.factory);
        widgets.put("btn", Button.factory);
    }
}

然而,正如您可能看到的,随着小部件类型的增加,这个列表变得越来越大,越来越笨拙,而且我还发现以这种方式集中小部件逻辑是非常丑陋的,因为每个小部件类型可以完全包含在自己的文件中。如果我能在每个定义小部件类的文件中做这样的事情,我会更喜欢:

public class Label extends Widget {
    static {
        Widget.register("lbl", new WidgetFactory() {...});
    }
}

但是,由于上述原因,这种特殊的方法显然是不可能的。

这并不是说我想不出任何方法来做到这一点,但它们似乎都拥有不同程度的丑陋,我也认为我真的不可能是第一个解决这个问题的人,所以我想问的是,是否至少有一些或多或少的"标准"方法来做这些事情。如果可以的话,我宁愿不要重新发明这个轮子。

我认为你可以保存id和小部件的类名,你需要在一个临时文件,然后使用反射实例化他们,也可以使用XML文件。

在启动时,遍历小部件包文件夹中的所有.class文件,并使用类加载器加载它们。例如,小部件的ID可以基于类名或存储在注释中。如果您愿意,您可以支持从几个小部件目录,从JAR文件等加载。

我相信有库可以帮助解决这个问题,希望有人能编辑这个答案,指向一个。

为了记录,我终于接受了这个问题似乎不存在标准解决方案的奇怪,所以我写了一个,它通过提供一个注释处理器来工作,该处理器将用Discoverable注释注释的类收集到生成的文本文件中。

当然,这仍然是一个集中的列表,但由于它是从分散的注释中自动生成的(这并不一定比GCC为C程序生成的初始化代码的自动生成ELF部分更奇怪),因此我对此没有问题。

最新更新