diff --git a/src/java.base/share/classes/java/time/format/DateTimeParseContext.java b/src/java.base/share/classes/java/time/format/DateTimeParseContext.java index 0a4c7e825a3b6..b65c9f8ff0ceb 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeParseContext.java +++ b/src/java.base/share/classes/java/time/format/DateTimeParseContext.java @@ -345,7 +345,7 @@ TemporalAccessor toResolved(ResolverStyle resolverStyle, Set reso * @return the value mapped to the specified field, null if field was not parsed */ Long getParsed(TemporalField field) { - return currentParsed().fieldValues.get(field); + return currentParsed().getFieldValue(field); } /** @@ -362,7 +362,7 @@ Long getParsed(TemporalField field) { */ int setParsedField(TemporalField field, long value, int errorPos, int successPos) { Objects.requireNonNull(field, "field"); - Long old = currentParsed().fieldValues.put(field, value); + Long old = currentParsed().putFieldValue(field, value); return (old != null && old.longValue() != value) ? ~errorPos : successPos; } diff --git a/src/java.base/share/classes/java/time/format/Parsed.java b/src/java.base/share/classes/java/time/format/Parsed.java index 1ec956dfa2cd3..6a098da2767f6 100644 --- a/src/java.base/share/classes/java/time/format/Parsed.java +++ b/src/java.base/share/classes/java/time/format/Parsed.java @@ -87,7 +87,6 @@ import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; -import java.time.ZonedDateTime; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; import java.time.chrono.ChronoZonedDateTime; @@ -98,6 +97,7 @@ import java.time.temporal.TemporalQueries; import java.time.temporal.TemporalQuery; import java.time.temporal.UnsupportedTemporalTypeException; +import java.util.EnumMap; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -128,7 +128,7 @@ final class Parsed implements TemporalAccessor { /** * The parsed fields. */ - final Map fieldValues = new HashMap<>(); + private Map fieldValues = initFieldValuesMap(); /** * The parsed zone. */ @@ -178,6 +178,10 @@ final class Parsed implements TemporalAccessor { Parsed copy() { // only copy fields used in parsing stage Parsed cloned = new Parsed(); + if (!(fieldValues instanceof EnumMap)) { + // Upgrade to a full TemporalField Map + cloned.fieldValues = new HashMap<>(this.fieldValues.size()); + } cloned.fieldValues.putAll(this.fieldValues); cloned.zone = this.zone; cloned.zoneNameType = this.zoneNameType; @@ -187,6 +191,29 @@ Parsed copy() { return cloned; } + + // A bit contorted way to get the map created. + @SuppressWarnings("unchecked") + private Map initFieldValuesMap() { + return (Map) (Object)new EnumMap(ChronoField.class); + } + + Long putFieldValue(TemporalField field, long value) { + try { + return fieldValues.put(field, value); + } catch (ClassCastException cce) { + // Upgrade to a full TemporalField Map + Map nmap = new HashMap<>(fieldValues.size() + 1); + nmap.putAll(fieldValues); + fieldValues = nmap; + return nmap.put(field, value); + } + } + + Long getFieldValue(TemporalField field) { + return fieldValues.get(field); + } + //----------------------------------------------------------------------- @Override public boolean isSupported(TemporalField field) { @@ -334,7 +361,7 @@ private void resolveFields() { } private void updateCheckConflict(TemporalField targetField, TemporalField changeField, Long changeValue) { - Long old = fieldValues.put(changeField, changeValue); + Long old = putFieldValue(changeField, changeValue); if (old != null && old.longValue() != changeValue.longValue()) { throw new DateTimeException("Conflict found: " + changeField + " " + old + " differs from " + changeField + " " + changeValue +