我创建了以下类来使用常量验证某些值。为什么我收到以下错误?由于不需要启动类来使用静态方法,但仍然为什么要尝试启动。我正在使用java 1.6 这是一个很好的做法吗?
public final class Approver{
// Avoids initiating this class
private Approver() {
}
private static final List<String> APPROVED_LENGTH= new ArrayList<String>() {
{
addAll(KM_APPROVED_LIST);
addAll(LM_APPROVED_LIST);
}
};
private static final List<String> KM_APPROVED_LIST = new ArrayList<String>() {
{
add("L");
add("G");
// so on
}
};
private static final List<String> LM_APPROVED_LIST = new ArrayList<String>() {
{
add("P");
add("K");
// so on
}
};
public static boolean isApproved(String lenth) {
return APRROVED_LENGTH.contains(length);
}
if(Approver.isApproved("K"))
{......}
Caused by: java.lang.NoClassDefFoundError: Could not initialize class ...Approver.class
答案 0 :(得分:6)
如果你看过剩下的错误,我想你已经看到了什么是错的。在这个声明中:
private static final List<String> APPROVED_LENGTH= new ArrayList<String>() {
{
addAll(KM_APPROVED_LIST);
addAll(LM_APPROVED_LIST);
}
};
你正在使用KM_APPROVED_LIST
和LM_APPROVED_LIST
,而他们都是null
...这意味着你正在调用addAll(null)
,这会抛出NullPointerException
}。
例如,这是我在一个简短的测试应用程序中看到的异常:
Exception in thread "main" java.lang.ExceptionInInitializerError
at Test.main(Test.java:43)
Caused by: java.lang.NullPointerException
at java.util.ArrayList.addAll(Unknown Source)
at Approver$1.<init>(Test.java:14)
at Approver.<clinit>(Test.java:12)
... 1 more
那时,应该很清楚发生了什么。
初始化static
块中的所有内容(IMO)会更加清晰 - 它会消除所有排序问题 - 以及避免令人讨厌的匿名类:
private static final List<String> APPROVED_LENGTH;
private static final List<String> KM_APPROVED_LIST;
private static final List<String> LM_APPROVED_LIST;
static {
KM_APPROVED_LIST = new ArrayList<String>();
KM_APPROVED_LIST.add("L");
KM_APPROVED_LIST.add("G");
LM_APPROVED_LIST = new ArrayList<String>();
LM_APPROVED_LIST.add("P");
LM_APPROVED_LIST.add("K");
APPROVED_LENGTH = new ArrayList<String>();
APPROVED_LENGTH.addAll(KM_APPROVED_LIST);
APPROVED_LENGTH.addAll(LM_APPROVED_LIST);
}
或者,您可以重新排序字段并依赖静态变量初始化程序排序 - 但最好使用Guava使代码更清晰:
private static final List<String> KM_APPROVED_LIST =
Lists.newArrayList("L", "G");
private static final List<String> LM_APPROVED_LIST =
Lists.newArrayList("P", "K");
private static final List<String> APPROVED_LENGTH =
Lists.newArrayList(Iterables.concat(KM_APPROVED_LIST, LM_APPROVED_LIST));
我应该指出只是重新排序字段声明,以便最后声明APPROVED_LENGTH
来解决问题 - 但它仍然不是很好的代码,IMO。
您可能也想考虑制作这些不可变列表。
答案 1 :(得分:-1)
错误正在发生,因为您正在尝试在静态上下文中创建匿名内部类:
private static final List<String> APPROVED_LENGTH= new ArrayList<String>() {
{
addAll(KM_APPROVED_LIST);
addAll(LM_APPROVED_LIST);
}
};
我很惊讶编译器允许这种情况发生,但我认为它不会进行大量的语义检查(即,验证可以实例化类)。无论如何,这里是如何修复它(以及一般初始化静态列表/地图的更好方法):
private static final List<String> APPROVED_LENGTH= new ArrayList<String>();
static {
addAll(KM_APPROVED_LIST);
addAll(LM_APPROVED_LIST);
};