Reputation: 3878
I have created the following class to validate certain values with constants. Why i am getting the following error? As the class need not to be initiated to use static methods, but still why it is trying to initiate. I am using java 1.6 Is this a good practice to do ?
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
Upvotes: 1
Views: 677
Reputation: 1500055
If you'd looked at the rest of the error, I think you've had seen what's wrong. In this statement:
private static final List<String> APPROVED_LENGTH= new ArrayList<String>() {
{
addAll(KM_APPROVED_LIST);
addAll(LM_APPROVED_LIST);
}
};
you're using KM_APPROVED_LIST
and LM_APPROVED_LIST
while they're both null
... which means you're calling addAll(null)
which will throw a NullPointerException
.
For example, here's the exception I see in a short test app:
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
At that point, it should be pretty clear what's going on.
It would be cleaner to initialize everything in a static
block, IMO - it takes all the ordering concerns away - as well as avoiding the nasty anonymous classes:
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);
}
Alternatively, you could reorder the fields and rely on the static variable initializer ordering - but preferably using Guava to make the code much clearer:
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));
I should point out that just reordering the field declarations so that APPROVED_LENGTH
is declared last fixes the problem - but it's still not nice code as-is, IMO.
You might also want to consider making these immutable lists, too.
Upvotes: 6
Reputation: 15
The error is happening because you're trying to create an anonymous inner class in a static context:
private static final List<String> APPROVED_LENGTH= new ArrayList<String>() {
{
addAll(KM_APPROVED_LIST);
addAll(LM_APPROVED_LIST);
}
};
I'm surprised that the compiler allows this to happen, but I suppose it doesn't do a lot of semantic checks (ie, verifying that the class can be instantiated). Regardless, here's how to fix it (and a better way to initialize static lists/maps in general):
private static final List<String> APPROVED_LENGTH= new ArrayList<String>();
static {
addAll(KM_APPROVED_LIST);
addAll(LM_APPROVED_LIST);
};
Upvotes: -1