I just hit very strange (to me) behaviour of java. I have following classes:
public abstract class Unit {
public static final Unit KM = KMUnit.INSTANCE;
public static final Unit METERS = MeterUnit.INSTANCE;
protected Unit() {
}
public abstract double getValueInUnit(double value, Unit unit);
protected abstract double getValueInMeters(double value);
}
And:
public class KMUnit extends Unit {
public static final Unit INSTANCE = new KMUnit();
private KMUnit() {
}
//here are abstract methods overriden
}
public class MeterUnit extends Unit {
public static final Unit INSTANCE = new MeterUnit();
private MeterUnit() {
}
///abstract methods overriden
}
And my test case:
public class TestMetricUnits extends TestCase {
@Test
public void testConversion() {
System.out.println("Unit.METERS: " + Unit.METERS);
System.out.println("Unit.KM: " + Unit.KM);
double meters = Unit.KM.getValueInUnit(102.11, Unit.METERS);
assertEquals(0.10211, meters, 0.00001);
}
}
- MKUnit and MeterUnit are both singletons initialized statically, so during class loading. Constructors are private, so they can't be initialized anywhere else.
- Unit class contains static final references to MKUnit.INSTANCE and MeterUnit.INSTANCE
I would expect that:
- KMUnit class is loaded and instance is created.
- MeterUnit class is loaded and instance is created.
- Unit class is loaded and both KM and METERS variable are initialized, they are final so they cant be changed.
But when I run my test case in console with maven my result is:
T E S T S
Running de.audi.echargingstations.tests.TestMetricUnits<br/>
Unit.METERS: m<br/>
Unit.KM: null<br/>
Tests run: 3, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.089 sec <<< FAILURE! - in de.audi.echargingstations.tests.TestMetricUnits<br/>
testConversion(de.audi.echargingstations.tests.TestMetricUnits) Time elapsed: 0.011 sec <<< ERROR!<br/>
java.lang.NullPointerException: null<br/>
at <br/>de.audi.echargingstations.tests.TestMetricUnits.testConversion(TestMetricUnits.java:29)
<br/>
Results :
Tests in error:
TestMetricUnits.testConversion:29 NullPointer
And the funny part is that, when I run this test from eclipse via JUnit runner everything is fine, I have no NullPointerException
and in console I have:
Unit.METERS: m
Unit.KM: km
So the question is: what can be the reason that KM variable in Unit is null (and in the same time METERS is not null)