Ich behebe gerade einen sehr seltsamen Fehler, bei dem ein private final val
innerhalb eines Objektfeldes nicht initialisiert wird, bevor auf sie zugegriffen wird. Die Position des Codes kann unter https://github.com/mdedetrich/soda-time/blob/master/jvm/src/main/scala/org/joda/time/chrono/GregorianChronology.scala#L12-L33 gefunden werden.Nicht initialisierte Felder in einem Objekt
Sie können diesen Fehler simulieren, indem Sie den obigen Repo und dann sodatimeJVM/console
ausführen und dann in der Konsole ausführen import org.joda.time._; DateTime.now(). MinusDays (10)
Der Code wurde hier gepostet
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)
Die letzte Zeile, das heißt var chronos: Array[GregorianChronology] = cCache.get(_zone)
eine java.lang.NullPointerException
wirft. Der Wert, der null ist, ist cCache
, aber das macht keinen Sinn, da es eindeutig bei private final val cCache = new ConcurrentHashMap[DateTimeZone, Array[GregorianChronology]]()
initialisiert wird. Wenn ich anstelle "-Xcheckinit"
Scala dann sagt mir scala.UninitializedFieldError: Uninitialized field: GregorianChronology.scala: 19
was auf private final val cCache = new ConcurrentHashMap[DateTimeZone, Array[GregorianChronology]]()
zeigt. Dies ist nicht sehr nützlich, da ich weiß, dass der Wert nicht initialisiert ist, das Problem ist, dass ich nicht weiß warum. Da es sich um ein finales val handelt, gehe ich davon aus, dass es einer der ersten Werte sein sollte, die initialisiert werden, vor allem bevor getInstance
jemals aufgerufen wird.
Ich weiß, dass ich den Wert faul machen kann, es zu beheben, das würde jedoch einen unnötigen Leistungseinbruch bringen. Was noch wichtiger ist, die äquivalente Java-Version private static final ConcurrentHashMap<DateTimeZone, GregorianChronology[]> cCache = new ConcurrentHashMap<DateTimeZone, GregorianChronology[]>()
funktioniert absolut gut.
Danke, sich so dumm fühlen, das zu verpassen! – mdedetrich