Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions src/java.base/share/classes/java/time/LocalDate.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamField;
import java.io.Serial;
import java.io.Serializable;
import java.time.chrono.ChronoLocalDate;
import java.time.chrono.IsoEra;
Expand Down Expand Up @@ -142,6 +144,22 @@
public final class LocalDate
implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {

/**
* For backward compatibility of the serialized {@code LocalDate.class} object,
* explicitly declare the types of the serialized fields as defined in JDK 1.8.
* Instances of {@code LocalDate} are serialized using the dedicated
* serialized form by {@code writeReplace}.
* @serialField year int The year.
* @serialField month short The month-of-year.
* @serialField day short The day-of-month.
*/
@Serial
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("year", int.class),
new ObjectStreamField("month", short.class),
new ObjectStreamField("day", short.class)
};

/**
* The minimum supported {@code LocalDate}, '-999999999-01-01'.
* This could be used by an application as a "far past" date.
Expand Down Expand Up @@ -178,15 +196,15 @@ public final class LocalDate
/**
* @serial The year.
*/
private final int year;
private final transient int year;
/**
* @serial The month-of-year.
*/
private final short month;
private final transient byte month;
/**
* @serial The day-of-month.
*/
private final short day;
private final transient byte day;

//-----------------------------------------------------------------------
/**
Expand Down Expand Up @@ -490,8 +508,8 @@ private static LocalDate resolvePreviousValid(int year, int month, int day) {
*/
private LocalDate(int year, int month, int dayOfMonth) {
this.year = year;
this.month = (short) month;
this.day = (short) dayOfMonth;
this.month = (byte) month;
this.day = (byte) dayOfMonth;
}

//-----------------------------------------------------------------------
Expand Down
26 changes: 21 additions & 5 deletions src/java.base/share/classes/java/time/MonthDay.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamField;
import java.io.Serial;
import java.io.Serializable;
import java.time.chrono.Chronology;
import java.time.chrono.IsoChronology;
Expand Down Expand Up @@ -133,6 +135,20 @@ public final class MonthDay
*/
@java.io.Serial
private static final long serialVersionUID = -939150713474957432L;

/**
* For backward compatibility of the serialized {@code MonthDay.class} object,
* explicitly declare the types of the serialized fields as defined in JDK 1.8.
* Instances of {@code MonthDay} are serialized using the dedicated
* serialized form by {@code writeReplace}.
* @serialField month int The month-of-year.
* @serialField day int The day-of-month.
*/
@Serial
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("month", int.class),
new ObjectStreamField("day", int.class)
};
/**
* Parser.
*/
Expand All @@ -144,13 +160,13 @@ public final class MonthDay
.toFormatter();

/**
* @serial The month-of-year, not null.
* @serial The month-of-year.
*/
private final int month;
private final transient byte month;
/**
* @serial The day-of-month.
*/
private final int day;
private final transient byte day;

//-----------------------------------------------------------------------
/**
Expand Down Expand Up @@ -319,8 +335,8 @@ public static MonthDay parse(CharSequence text, DateTimeFormatter formatter) {
* @param dayOfMonth the day-of-month to represent, validated from 1 to 29-31
*/
private MonthDay(int month, int dayOfMonth) {
this.month = month;
this.day = dayOfMonth;
this.month = (byte) month;
this.day = (byte) dayOfMonth;
}

//-----------------------------------------------------------------------
Expand Down
24 changes: 20 additions & 4 deletions src/java.base/share/classes/java/time/YearMonth.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamField;
import java.io.Serial;
import java.io.Serializable;
import java.time.chrono.Chronology;
import java.time.chrono.IsoChronology;
Expand Down Expand Up @@ -137,6 +139,20 @@ public final class YearMonth
*/
@java.io.Serial
private static final long serialVersionUID = 4183400860270640070L;

/**
* For backward compatibility of the serialized {@code YearMonth.class} object,
* explicitly declare the types of the serialized fields as defined in JDK 1.8.
* Instances of {@code YearMonth} are serialized using the dedicated
* serialized form by {@code writeReplace}.
* @serialField year int The year.
* @serialField month int The month-of-year.
*/
@java.io.Serial
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("year", int.class),
new ObjectStreamField("month", int.class),
};
/**
* Parser.
*/
Expand All @@ -149,11 +165,11 @@ public final class YearMonth
/**
* @serial The year.
*/
private final int year;
private final transient int year;
/**
* @serial The month-of-year, not null.
* @serial The month-of-year..
*/
private final int month;
private final transient byte month;

//-----------------------------------------------------------------------
/**
Expand Down Expand Up @@ -306,7 +322,7 @@ public static YearMonth parse(CharSequence text, DateTimeFormatter formatter) {
*/
private YearMonth(int year, int month) {
this.year = year;
this.month = month;
this.month = (byte) month;
}

/**
Expand Down
14 changes: 7 additions & 7 deletions src/java.base/share/classes/java/time/chrono/HijrahDate.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -137,11 +137,11 @@ public final class HijrahDate
/**
* The month-of-year.
*/
private final transient int monthOfYear;
private final transient byte monthOfYear;
/**
* The day-of-month.
*/
private final transient int dayOfMonth;
private final transient byte dayOfMonth;

//-------------------------------------------------------------------------
/**
Expand Down Expand Up @@ -273,8 +273,8 @@ private HijrahDate(HijrahChronology chrono, int prolepticYear, int monthOfYear,

this.chrono = chrono;
this.prolepticYear = prolepticYear;
this.monthOfYear = monthOfYear;
this.dayOfMonth = dayOfMonth;
this.monthOfYear = (byte) monthOfYear;
this.dayOfMonth = (byte) dayOfMonth;
}

/**
Expand All @@ -287,8 +287,8 @@ private HijrahDate(HijrahChronology chrono, long epochDay) {

this.chrono = chrono;
this.prolepticYear = dateInfo[0];
this.monthOfYear = dateInfo[1];
this.dayOfMonth = dateInfo[2];
this.monthOfYear = (byte) dateInfo[1];
this.dayOfMonth = (byte) dateInfo[2];
}

//-----------------------------------------------------------------------
Expand Down
18 changes: 17 additions & 1 deletion test/jdk/java/time/test/java/time/TestLocalDate.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -65,6 +65,8 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.io.ObjectStreamClass;
import java.io.ObjectStreamField;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.Month;
Expand Down Expand Up @@ -515,4 +517,18 @@ public void test_minus_QuarterYears(long quarterYears) {
.minus(quarterYears, ChronoUnit.MONTHS);
assertEquals(t0, t1);
}

// Verify serialized fields types are backward compatible
@Test
public void verifySerialFields() {
var osc = ObjectStreamClass.lookup(LocalDate.class);
for (ObjectStreamField f : osc.getFields()) {
switch (f.getName()) {
case "year" -> assertEquals(f.getType(), int.class, f.getName());
case "month",
"day" -> assertEquals(f.getType(), short.class);
default -> fail("unknown field in LocalDate: " + f.getName());
}
}
}
}
18 changes: 17 additions & 1 deletion test/jdk/java/time/test/java/time/TestMonthDay.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -62,7 +62,10 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.io.ObjectStreamClass;
import java.io.ObjectStreamField;
import java.time.LocalDate;
import java.time.Month;
import java.time.MonthDay;
Expand Down Expand Up @@ -144,4 +147,17 @@ void doTest_comparisons_MonthDay(MonthDay... localDates) {
}
}


// Verify serialized fields types are backward compatible
@Test
public void verifySerialFields() {
var osc = ObjectStreamClass.lookup(MonthDay.class);
for (ObjectStreamField f : osc.getFields()) {
switch (f.getName()) {
case "month",
"day" -> assertEquals(f.getType(), int.class, f.getName());
default -> fail("unknown field in MonthDay: " + f.getName());
}
}
}
}
20 changes: 19 additions & 1 deletion test/jdk/java/time/test/java/time/TestYearMonth.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -59,10 +59,16 @@
*/
package test.java.time;

import java.io.ObjectStreamClass;
import java.io.ObjectStreamField;
import java.time.LocalDate;
import java.time.YearMonth;

import org.testng.annotations.Test;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

/**
* Test YearMonth.
*/
Expand All @@ -75,4 +81,16 @@ public void test_immutable() {
assertImmutable(YearMonth.class);
}

// Verify serialized fields types are backward compatible
@Test
public void verifySerialFields() {
var osc = ObjectStreamClass.lookup(YearMonth.class);
for (ObjectStreamField f : osc.getFields()) {
switch (f.getName()) {
case "year" -> assertEquals(f.getType(), int.class, f.getName());
case "month" -> assertEquals(f.getType(), int.class, f.getName());
default -> fail("unknown field in YearMonth: " + f.getName());
}
}
}
}