Summary
-------
Make the cached hash code in `java.text.DecimalFormatSymbols` not serializable by adding `transient` keyword to its field declaration.
Problem
-------
Since JDK15, `java.text.DecimalFormatSymbols` started caching the hash code which is lazily initialized at the first `hashCode()` invocation. As the field is declared as non-transient, the value is serialized and reused when it is read in `readObject()`. Although it won't cause any issue if serialize/deserialize is being done in JDK15 as the value calculation is fixed, the code should not rely on that implementation detail, as hash codes are not required to remain consistent beyond JVM invocations.
Solution
--------
Add `transient` keyword to the cached hash code field so that it won't be serialized. The field will always be zero-reset on each object construction so that the value is calculated on its first invocation of `hashCode()` method.
Specification
-------------
Change the cached hash code field declaration as follows:
-- a/src/java.base/share/classes/java/text/DecimalFormatSymbols.java
+++ b/src/java.base/share/classes/java/text/DecimalFormatSymbols.java
@@ -760,7 +760,6 @@
/**
* Override hashCode.
*/
- private volatile int hashCode;
@Override
public int hashCode() {
if (hashCode == 0) {
@@ -1148,6 +1147,11 @@
private transient Currency currency;
private transient volatile boolean currencyInitialized;
+ /**
+ * Cached hash code.
+ */
+ private transient volatile int hashCode;
+
// Proclaim JDK 1.1 FCS compatibility
@java.io.Serial
static final long serialVersionUID = 5772796243397350300L;