[英]Java - static initializers in imported projects
所以我有两个项目A和B,项目B在项目A中导入,而在项目BI中则想要初始化一些具有静态初始化程序的对象。 问题是,它们没有被调用(已经使用final
关键字测试,没有帮助)。
所以我实际上想要一个小系统,它应该采用这种方式(这里描述的每个类都在项目B中):
addClassToLoad()
*方法来添加其他类(当调用类A中的方法start()
时将被“加载”); addClassToLoad()
; start()
,类A列出它已经获得的所有类,并调用方法onLoad()
(在*中解释)。 每个方法都是静态的,所以它只是一个(没有“实例化”)。
可悲的是,静态初始化器没有被调用。
问题是:我做错了什么(或者根本不可能)或者可能有另一种方法来做这个小系统? (我只是不想在A类中写关于每个类,必须在start()
方法中加载)
* addClassToLoad()
接受一个onLoad()
方法的接口,因此在A类中调用方法start()
会调用它
在代码版本中:
A类:
public class A {
private static ArrayList<ClassToLoad> classesToLoad;
public static void addClassToLoad(ClassToLoad c) {
if (classesToLoad == null)
classesToLoad = new ArrayList<ClassToLoad>();
classesToLoad.add(c);
}
public static void start() {
for (ClassToLoad c : classesToLoad) {
c.onLoad();
}
}
}
B级(和其他人(C,D等)一样):
public class B {
static {
A.addClassToLoad(new ClassToLoad() {
public void onLoad() {
load();
}
});
}
private static void load() {
// do something here on load ...
}
}
class ClassToLoad:
public interface ClassToLoad {
public void onLoad();
}
添加新的JDBC驱动程序时,这是同样的问题,为什么必须调用Class.forName()来注册JDBC驱动程序。 每个JDBC驱动程序类都有一个静态初始化程序,用于向DriverManager注册自己。 为什么? 默认情况下,类加载器不会加载jar文件中的所有类。 只有在执行期间引用类时才加载类,这很聪明,因为类加载器永远不必将这些未使用的类加载到内存中。 因此,要解决您的问题,您必须设法在调用start()之前加载这些类,例如Class.forName()。 如果使用spring,则可以在configure中创建所有这些类的列表。 Spring还提供了一个util来扫描某些类型的类的包,然后你可以指定要扫描的包名。
当ClassLoader第一次加载类时,将设置静态字段和静态初始化程序(静态块)。 Rembemer将在给定的类中发生这种情况将首次使用,因为ClassLoader以惰性方式加载类(如果需要)
所以我似乎不可能执行那些静态块,所以我将每个需要加载的类添加到A类中,这样它们实际上加载时没有任何问题(在项目B中)。 在项目AI中,显然需要在主类中添加我需要加载的其他类。
所以我把这些类作为单身人士,所以他们实际上已经加载并准备好“主要”加载,启动和处理。 所以添加类看起来像这样:
A.addClassToLoad(B.getInstance());
我使用类ClassToLoad
作为通用类加载(听起来很有趣),虽然我将其重命名为SystemCycle
。
所以作为B类示例的代码现在看起来像这样:
public class B implements SystemCycle {
private static B instance = new B();
private B() {}
public static void getInstance() {
return instance;
}
public void onLoad() { /* some code here */ }
public void onLaunch() { /* some code here */ }
public void onDispose() { /* some code here */ }
}
SystemCycle
类现在看起来像这样:
public interface SystemCycle {
public void onLoad();
public void onLaunch();
public void onDispose();
}
嗯,这很明显,因为B类的例子。
我甚至做了一个小的检查系统,所以如果用户试图调用其中一个方法,它将被忽略,因为实现SystemCycle
的类检查A类是否实际上正在加载,启动或处置。 但如果没有,它就可以return
。 (尽管如果usermade类没有检查它,它可能会被其他用户制作的类滥用)。
我的项目中的PS addClassToLoad
实际上叫做addSystemToLoad
,所以我这样做就是为了让一个例子更容易理解。
小编辑:我甚至首先尝试使用注释,但即使那件事也没有帮助我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.