静态初始化不叫上创建活动 [英] Static initializer not called on Activity creation
问题描述
我有以下的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屋!