静态初始化不叫上创建活动 [英] Static initializer not called on Activity creation

查看:199
本文介绍了静态初始化不叫上创建活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code在我的主要活动:

I have the following code in my main Activity:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Fabric.with(this, new Crashlytics());
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        MyClass[] arr = MyClass.values();
        System.out.println(Arrays.deepToString(arr));

MyClass的情况如下:

MyClass is as follow:

public class MyClass {

    public static MyClass A;
    public static MyClass B;
    public static MyClass C;

    static {
        System.out.println("Invoked");
        A = new MyClass("a");
        B = new MyClass("b");
        C = new MyClass("c");
    }

    private static Map<String, MyClass> values = null;
    private final String name;

    private MyClass(String name) {
        this.name = name;
        if (values == null)
            values = new HashMap<>();
        values.put(name, this);
    }

    public static MyClass[] values() {
        return values.values().toArray(new MyClass[values.size()]);
    }
}

我的问题是,值()触发 NullPointerException异常,因为为空,即静态初始化块似乎并没有被调用。尽管如此,调用控制台出appers,所以初始化块确实被调用。

My issue is that values() triggers a NullPointerException, as values is null, i.e. the static initialization block seems not to be invoked. Nevertheless, the console out "Invoked" appers, so the initialization block DOES get called.

怎么了?

编辑:这个问题是严格地与这样的:问题静态$ C $下在Android的

this question is strictly related to this: Issue with static code in Android

推荐答案

这是因为私有静态地图&LT;弦乐,MyClass的&GT;值= NULL; 是静态初始化后:这项任务将要运行的之后的的静态初始化块,所以它被分配一个非空值,然后调零了

It's because private static Map<String, MyClass> values = null; is after the static initializer: this assignment will be run after the static initializer block, so it is being assigned a non-null value, and then nulled out.

初​​始化块之前移动字段。

Move the values field before the initializer block.

顺便说一句,我会创建 MyClass的的实例时解耦实例的创建从它们插入到地图上,以消除副作用。你也可以不用一个静态初始化块:

BTW, I would decouple the creation of the instances from inserting them into the map, in order to remove the side effects when creating an instance of MyClass. You can also do it without a static initializer block:

public class MyClass {
    private static final Map<String, MyClass> values = new HashMap<>();

    public static final MyClass A = register(new MyClass("a"));
    public static final MyClass B = register(new MyClass("b"));
    public static final MyClass C = register(new MyClass("c"));

    private static MyClass register(MyClass instance) {
      values.put(instance.name, instance);
      return instance;
    }

    private MyClass(String name) {
      this.name = name;
    }
    // ...
}

其实,我甚至不会做到这一点:我会使用枚举 - 但我想有东西在你真正的code,它阻止你这样做。

Actually, I wouldn't even do this: I'd use an enum - but I guess there is something in your real code that stops you from doing that.

这篇关于静态初始化不叫上创建活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆