繁体   English   中英

Java - 导入项目中的静态初始化程序

[英]Java - static initializers in imported projects

所以我有两个项目A和B,项目B在项目A中导入,而在项目BI中则想要初始化一些具有静态初始化程序的对象。 问题是,它们没有被调用(已经使用final关键字测试,没有帮助)。

所以我实际上想要一个小系统,它应该采用这种方式(这里描述的每个类都在项目B中):

  • class A是一个主类,你可以在其中调用addClassToLoad() *方法来添加其他类(当调用类A中的方法start()时将被“加载”);
  • 类B,C和D从其静态初始化程序调用方法addClassToLoad() ;
  • 当项目A中的某个类调用方法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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM