我刚刚遇到了非常奇怪的(对我而言)java 行为。我有以下课程:
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);
}
和:
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
}
还有我的测试用例:
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 和 MeterUnit 都是静态初始化的单例,因此在类加载期间。构造函数是私有的,因此它们不能在其他任何地方初始化。
- Unit 类包含对 MKUnit.INSTANCE 和 MeterUnit.INSTANCE 的静态最终引用
我希望:
- 加载 KMUnit 类并创建实例。
- 加载 MeterUnit 类并创建实例。
- 单元类被加载并且 KM 和 METERS 变量都被初始化,它们是最终的,所以它们不能被改变。
但是当我使用 maven 在控制台中运行我的测试用例时,我的结果是:
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
有趣的是,当我通过 JUnit runner 从 eclipse 运行这个测试时,一切都很好,我没有NullPointerException
,在控制台中我有:
Unit.METERS: m
Unit.KM: km
所以问题是:Unit中的KM变量为空的原因是什么(同时METERS不为空)