私は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 クラスが読み込まれ、インスタンスが作成されます。
- Unit クラスがロードされ、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ランナーを介してEclipseからこのテストを実行すると、すべて問題なくNullPointerException
、コンソールにはありません。
Unit.METERS: m
Unit.KM: km
問題は、Unit の KM 変数が nullである (同時に METERS が null ではない)理由は何であるかということです。