在Java

时间:2017-05-27 10:09:48

标签: java static initialization

我正在尝试创建一个自动创建自己的子类。我定义了Base,其中包含实例列表。然后我用静态成员Derived定义了regreg已通过调用Base.Register()进行初始化,并将其添加到实例列表中。

main()我正在打印Base的实例列表。但是没有初始化,我收到错误 - 实例列表是null

在进一步尝试中,我添加了BooleansBase的列表。每当我注册一个实例时,我都会更改此列表。我还在程序中打印此列表。我希望它强制执行Base.register(),但无济于事。

我找到了一个有效的解决方案,但我不欣赏 - 我可以打印保存在Base.register()中的Derived的结果。这会强制静态初始化。但是,我打算将解决方案用于一堆派生类,我不想直接调用每个派生类。

有没有办法强制静态初始化?

我想我可以使用反射,我现在试图避免这种情况。

编辑我实际上要做的是构建一组派生类(用于单元测试)。所有类派生Base。我想避免为每个单独创建实例的需要。我试图在每个派生类代码(仅)中获得通用解决方案。这样的解决方案很容易复制和解决。糊。

public class StaticTest {

    private static class Base{
        private static ArrayList<Base> _instances = null;
        private static ArrayList<Boolean> _regs = null;
        public static int _count = 0;
        public static void init(){
            _regs = new ArrayList<>();
            for (int i=0;i<10;i++)
                _regs.add(false);
        }
        protected static boolean register(Base b)
        {
            if (_instances == null)
                _instances = new ArrayList<>();

            _regs.set(_count++, true);

            return _instances.add(b);
        }

        public static void printAll(){
            for (Boolean b: _regs)
                System.out.printf("hello %s%n", b.toString());
            for (Base b: _instances)
                System.out.printf("hello %s%n", b.toString());
        }
    }

    private static class Derived extends Base{
        public static boolean _reg = Base.register(new Derived());
    }

    public static void main(String[] args) {
        //System.out.print(Derived._reg ? "0" : "1");
        Base.init();
        System.out.printf("Base._count = %d%n",Base._count);
        Base.printAll();
    }

}

1 个答案:

答案 0 :(得分:0)

简短回答是静态初始化仅在首次使用类时发生。当您调用Base.init()时,Derived还没有被使用,所以注册没有被调用。

中等答案是,如果取消注释System.out行,则会得到NullPointerException,因为在init之前,Derived调用中的静态代码会初始化Arraylist。将init移动到第一行可以解决问题,并且可以按照您的意愿工作。

最后的答案,如果您正在尝试了解Java类的初始化方式及其限制,那就没关系,但是您尝试编写的机制非常糟糕设计。请提供您尝试解决的真正问题,有人可以指出您正确的方向。