java - Java中自注册对象的静态 block 无法执行

标签 java

解释起来有点棘手,但假设我有两个类 ABA 包含工厂对象的静态 列表,这些工厂对象由提供此类因子的每个对象注册。在此示例中,B 就是这样一个类,并提供了一个虚构的 Factory 实现。

A类:

public class A {
    protected static Map<String, Factory> registered = new HashMap<String, Factory>();
    protected static register(String name, Factory factory) {
        registered.put(name, factory);
    }

    public A() {
        // Do something with the factories we've registered
    }
}

B类:

public class B {
    static {
        A.register("Foo", new Factory() {
            public Object create() {
                return new B();
            }
        });
    }

    public B() {
        // Create a new instance of class B
    }
}

在我的程序中,由于某种奇怪的原因,B 中的静态 block 从未被调用,因此当我开始与 A 交互时,没有注册任何工厂,因此它无法做它需要做的事情。

如果我将每个Factory的创建直接移到A中,当然没有问题。我的工作假设是,由于编译器无法识别的任何类都没有对 B 的明确引用,因此 AB 之间存在链接 所以根本不用担心 B 。我能做些什么来解决这个问题吗?我希望避免直接将每个新工厂添加到 A 中,因为这使得维护比让新工厂简单地注册自己更困难,但显然让它们根本不起作用更糟糕;尽管如此,如果可以的话,我还是想以某种方式让它按预期工作。

如果相关的话,我正在使用的特定 JVM 是 Android JVM,这可能是该 JVM 正在使用的某些优化的副作用吗?

最佳答案

您可以在this blog post中阅读有关类加载的信息。 。要点是类在被引用之前不会被加载。并且类的静态 block 在类被加载之前不会被执行。规则是

  1. 类的实例是使用 new() 关键字或使用 class.forName() 进行反射创建的,这可能会在 Java 中抛出 ClassNotFoundException。
  2. 调用类的静态方法。
  3. 分配了 Class 的静态字段。
  4. 使用类的静态字段,它不是常量变量。
  5. if Class 是顶级类,并且执行按词法嵌套在类中的断言语句。

解决方案是实例化 B 或调用无操作静态方法(或上述任何方法)。

public class B {
    static {
        A.register("Foo", new Factory() {
            public Object create() {
                return new B();
            }
        });
    }

    public void static noOp() {}

    public B() {
        // Create a new instance of class B
    }
}

...

B.noOp();

Oracle JVM 规范指出了这一点 here .

关于java - Java中自注册对象的静态 block 无法执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18538342/

相关文章:

java - 使用扫描仪类读取 txt 文件时会出现 InputMismatchException。我究竟做错了什么?

java - 在java中添加对象到数组列表

java - struts2中执行并等待拦截器

在 jsp 中的两个不同表单上使用两个提交按钮时出现 Java 错误

java - JButton 不产生输出 - 石头剪刀布游戏(GUI,Java)

java - 如何在没有来自所有者实体的链接的情况下在 JPA 中指定依赖项?

java - 如何在 Java 中使用 ArrayList

java - RXJava BehaviorSubject 的 Asnyc 初始化

java - JPA 查询调用 getter 数百万次

java - JDK问题: interrupt another thread blocked on an IO operation with signal may fail