我绝对不知道为什么以下代码不断抛出NullpointerExceptions。我无法理解或调试它(从较大的类中删除它的代码)......
代码基于“枚举模式”,我希望保留类中包含的所有“常量”的列表/映射(我可能正在使用Reflection,但使用List / Map更容易...)
public class Country {
public static final Country SWITZERLAND = new Country("SWITZERLAND");
private static ArrayList<Country> countries = new ArrayList<Country>();
private Country(String constname) {
//constname is currently not used (I will use it for a Key in a Map)
System.out.println(constname);
System.out.println("Ref debug:"+this);
//Ad this to the Countries
Country.countries.add(this);
}
}
非常感谢帮助。我在这里缺少什么?
答案 0 :(得分:5)
SWITZERLAND
可能会在 countries
之前初始化,这也是static
。因此,countries
的构造函数调用中null
仍为SWITZERLAND
。
要强制定义良好的初始化顺序,请使用static
块:
public class Country {
public static final Country SWITZERLAND;
private static ArrayList<Country> countries;
static {
countries = new ArrayList<Country>();
SWITZERLAND = new Country("SWITZERLAND");
}
}
答案 1 :(得分:4)
为了扩展Konrad所说的内容,静态变量初始值设定项以文本顺序执行(如JLS section 8.7中所述)。如果您先放置ArrayList
,它将起作用:
public class Country {
private static ArrayList<Country> countries = new ArrayList<Country>();
public static final Country SWITZERLAND = new Country("SWITZERLAND");
...
Konrad建议使用静态构造函数来明确指定顺序是一个很好的建议。
您使用的是Java“pre 1.5”吗?如果没有,请使用直接枚举...
答案 2 :(得分:4)
因为我认为这比乔恩所说的更为粗略:
“类型安全枚举模式”已过时!
除非你被迫使用古老的Java版本(1.5之前,Sun甚至不再支持),否则你应该使用Java的real Enums,这可以为你节省大量的工作和麻烦(因为旧版本)风格的类型安全的枚举很难得到正确的,并且只是一切都很棒。
答案 3 :(得分:1)
初始化SWITZERLAND
静态字段的'Country'构造函数调用在countries
列表初始化之前发生。如果更改静态字段定义的顺序,它将更好。
答案 4 :(得分:-1)
我认为下面的代码可能有效。类的构造函数必须定义为非私有的公共方法。
国家(字符串constname){
//当前未使用constname(我将其用于Map中的Key)
的System.out.println(constname);
System.out.println(“Ref debug:”+ this);
//Ad this to the Countries
Country.countries.add(this);
}