Java 创建活动时未调用静态初始值设定项
我的主要活动中有以下代码:Java 创建活动时未调用静态初始值设定项,java,android,static,Java,Android,Static,我的主要活动中有以下代码: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fabric.with(this, new Crashlytics()); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewB
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如下所示:
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()]);
}
}
公共类MyClass{
甲级公共图书馆;
B类公共设施;
C类公共场所;
静止的{
System.out.println(“已调用”);
A=新的MyClass(“A”);
B=新的MyClass(“B”);
C=新的MyClass(“C”);
}
私有静态映射值=null;
私有最终字符串名;
私有MyClass(字符串名称){
this.name=名称;
如果(值==null)
values=newhashmap();
value.put(name,this);
}
公共静态MyClass[]值(){
返回values.values().toArray(新的MyClass[values.size()]);
}
}
我的问题是values()
会触发NullPointerException
,因为values
为空,即静态初始化块似乎不会被调用。尽管如此,还是会出现控制台out“Invoked”,因此会调用初始化块
怎么了
编辑:这个问题与此严格相关:这是因为
私有静态映射值=null
位于静态初始值设定项之后:此赋值将在静态初始值设定项块之后运行,因此将为其分配一个非null值,然后将其清除
将值
字段移到初始值设定项块之前
顺便说一句,为了消除创建
MyClass
实例时的副作用,我会将实例的创建与将它们插入映射分离。也可以在不使用静态初始值设定项块的情况下执行此操作:
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;
}
// ...
}
公共类MyClass{
私有静态最终映射值=新HashMap();
公共静态最终MyClass A=寄存器(新MyClass(“A”));
公共静态最终MyClass B=寄存器(新MyClass(“B”);
公共静态最终MyClass C=寄存器(新MyClass(“C”);
私有静态MyClass寄存器(MyClass实例){
value.put(instance.name,instance);
返回实例;
}
私有MyClass(字符串名称){
this.name=名称;
}
// ...
}
实际上,我甚至不会这样做:我会使用一个
枚举
——但我想你的真实代码中有某种东西阻止你这么做。这是因为私有静态映射值=null
位于静态初始值设定项之后:此赋值将在静态初始值设定项块之后运行,因此将为其分配一个非null值,然后将其清除
将值
字段移到初始值设定项块之前
顺便说一句,为了消除创建
MyClass
实例时的副作用,我会将实例的创建与将它们插入映射分离。也可以在不使用静态初始值设定项块的情况下执行此操作:
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;
}
// ...
}
公共类MyClass{
私有静态最终映射值=新HashMap();
公共静态最终MyClass A=寄存器(新MyClass(“A”));
公共静态最终MyClass B=寄存器(新MyClass(“B”);
公共静态最终MyClass C=寄存器(新MyClass(“C”);
私有静态MyClass寄存器(MyClass实例){
value.put(instance.name,instance);
返回实例;
}
私有MyClass(字符串名称){
this.name=名称;
}
// ...
}
实际上,我甚至不会这样做:我会使用
枚举
——但我想在您的真实代码中有某种东西阻止您这样做。值
不是由静态初始值设定项块初始化的。。。为什么不直接给它分配一个新的HashMap
呢?静态初始值设定项调用构造函数,而初始化构造函数是。另外,如果我在静态块中初始化它,我仍然会得到相同的错误。值
不是由静态初始值设定项块初始化的。。。为什么不直接给它分配一个新的HashMap
?静态初始值设定项调用构造函数,初始化是。另外,如果我在静态块中初始化它,我仍然会得到相同的错误。谢谢,这非常有趣,在开始时移动我的变量定义修复了我的问题。然而,我不确定“不要给它指定一个明确的值”是否有效。看看我的另一个问题,我没有给它指定一个特定的值。好的,我已经删除了那个部分。谢谢你的更新。我对枚举的问题是我需要建立一些层次结构。谢谢,这非常有趣,在开始时移动我的变量定义解决了我的问题。然而,我不确定“不要给它指定一个明确的值”是否有效。看看我的另一个问题,我没有给它指定一个特定的值。好的,我已经删除了那个部分。谢谢你的更新。我对枚举的问题是,我需要建立一些层次结构。