Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的全局代码初始化_Java_Initialization - Fatal编程技术网

Java中的全局代码初始化

Java中的全局代码初始化,java,initialization,Java,Initialization,由于JVM按需加载类和代码,因此除了包含主函数的类之外,没有办法在某个随机类中包含初始化代码,并在JVM启动时让它运行。我知道这种想法与JVM设计背道而驰。然而,有时候你想做这样的事情,我很好奇,除了有一个函数,它有一个长的,集中的初始化函数列表,可以在某个地方调用,并从主函数调用它们之外,是否还有一些标准的方法来做这件事 我想知道的具体原因是因为我有一个带有GUI系统的程序。这个程序连接到一个服务器,其行为有点像一个图形终端,允许服务器创建与用户交互的小部件。为了做到这一点,小部件需要有某种I

由于JVM按需加载类和代码,因此除了包含主函数的类之外,没有办法在某个随机类中包含初始化代码,并在JVM启动时让它运行。我知道这种想法与JVM设计背道而驰。然而,有时候你想做这样的事情,我很好奇,除了有一个函数,它有一个长的,集中的初始化函数列表,可以在某个地方调用,并从主函数调用它们之外,是否还有一些标准的方法来做这件事

我想知道的具体原因是因为我有一个带有GUI系统的程序。这个程序连接到一个服务器,其行为有点像一个图形终端,允许服务器创建与用户交互的小部件。为了做到这一点,小部件需要有某种ID,服务器可以使用它通过协议引用它们,并且需要有这种ID的某种注册表。现在,我正在使用此类ID的全局映射,映射到WidgetFactory类的实例,并在基本小部件类的静态{}块中初始化这些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);
    }
}
但是,由于上述原因,这种特殊的方法显然是不可能的


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

我认为您可以将所需的小部件的id和类名保存在临时文件中,然后使用反射来实例化它们,也可以使用xml文件

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


我确信有一些库可以帮助解决这个问题,希望有人能编辑这个答案,指出其中的一个。

为了记录在案,我终于接受了一个奇怪的事实,即这个问题似乎不存在标准解决方案,所以我,它的工作原理是提供一个注释处理器,该处理器将带有可发现注释的类收集到生成的文本文件中


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

为什么不将小部件列表存储在服务器上,然后编写一个简单的请求函数来加载它们呢?啊,数据库的奇迹…@Jlange:主要是因为我不想让服务器知道有关客户端实现的隐私信息,比如特定的类名,甚至不想知道它是用Java编写的。无论哪种方式,我都希望摆脱全局列表,而不仅仅是移动它;但是,没有可移植的方法来迭代类文件。并不是所有的类加载器都继承自URLClassLoader,我的程序可能是从不寻常的JNLP客户端启动的,所以我不能假设是这样。你能在编译期间扫描完全限定的小部件类名列表,然后在运行时扫描ClassLoader.loadClass吗?使用一个小的ant插件或类似的插件?将列表存储在ClassLoader.getResource可以获取的位置,或者如果无法获取,则使用列表生成Java代码。是的,这是我正在考虑的解决方案之一,但我仍然想知道是否有某种或多或少标准化的方法来实现这一点,而不是必须为其发明自己的解决方案。
public class Label extends Widget {
    static {
        Widget.register("lbl", new WidgetFactory() {...});
    }
}