現在、オブジェクトフィールド内のprivate final val
がアクセスされる前に初期化されていない非常に奇妙なエラーが修正されています。コードの場所はhttps://github.com/mdedetrich/soda-time/blob/master/jvm/src/main/scala/org/joda/time/chrono/GregorianChronology.scala#L12-L33です。オブジェクト内の初期化されていないフィールド
上記エラーをシミュレートしてsodatimeJVM/console
を実行してから、コンソールで `import org.joda.time._; DateTime.now()。minusDays(10)
コード、すなわちvar chronos: Array[GregorianChronology] = cCache.get(_zone)
がjava.lang.NullPointerException
をスローし、ここで
object GregorianChronology {
private final val MILLIS_PER_YEAR = (365.2425 * DateTimeConstants.MILLIS_PER_DAY).toLong
private final val MILLIS_PER_MONTH = (365.2425 * DateTimeConstants.MILLIS_PER_DAY/12).toLong
private final val DAYS_0000_TO_1970 = 719527
private final val MIN_YEAR = -292275054
private final val MAX_YEAR = 292278993
private final val INSTANCE_UTC = getInstance(DateTimeZone.UTC)
private final val cCache = new ConcurrentHashMap[DateTimeZone, Array[GregorianChronology]]()
def getInstanceUTC(): GregorianChronology = INSTANCE_UTC
def getInstance(): GregorianChronology = getInstance(DateTimeZone.getDefault, 4)
def getInstance(zone: DateTimeZone): GregorianChronology = getInstance(zone, 4)
def getInstance(zone: DateTimeZone, minDaysInFirstWeek: Int): GregorianChronology = {
var _zone: DateTimeZone = zone
if (_zone == null) {
_zone = DateTimeZone.getDefault
}
var chrono: GregorianChronology = null
var chronos: Array[GregorianChronology] = cCache.get(_zone)
最後の行を掲載されています。 nullの値はcCache
ですが、これは明らかにprivate final val cCache = new ConcurrentHashMap[DateTimeZone, Array[GregorianChronology]]()
で初期化されているので意味がありません。 "-Xcheckinit"
Scalaをオンにすると、private final val cCache = new ConcurrentHashMap[DateTimeZone, Array[GregorianChronology]]()
を指すscala.UninitializedFieldError: Uninitialized field: GregorianChronology.scala: 19
と表示されます。値が初期化されていないことを知っているので、これはあまり役に立ちません。問題はわかりません。なぜですか?その最終的な値から、特に初期化された最初の値の1つであることが前提です。特に、getInstance
が呼び出される前です。
私はそれを修正するために怠惰な値を作ることができますが、それは不必要なパフォーマンスヒットを招くことになります。さらに重要なのは、同等のJavaバージョンprivate static final ConcurrentHashMap<DateTimeZone, GregorianChronology[]> cCache = new ConcurrentHashMap<DateTimeZone, GregorianChronology[]>()
が問題なく動作することです。
ありがとう、それを逃して愚かな気分! – mdedetrich