JEP 405 Record Patterns and Backwards Compatible Changes

Brian Goetz brian.goetz at oracle.com
Mon Jun 13 02:38:32 UTC 2022


First, the JLS does not commit that changing the record descriptor is a 
compatible change of any kind, binary or source.  But as you say, you 
can render this "mostly compatible" by adding a constructor with the old 
record descriptor, which provides a reasonable default for the new 
components (if they are added at the end; if added in the middle, you're 
just out of luck.)

Binary compatibility: given the current implementation, old match sites 
will continue to link after adding a record parameter, because both the 
instanceof test and the accessor invocations based on the old record 
descriptor still work the same way based on the new descriptor.

As to source compatibility, you are correct that you are not yet able to 
declare the deconstruction pattern with the old record descriptor the 
same way you can currently with the constructor; eventually you will be 
able to do so, gaining parity with the constructor.

On 6/11/2022 8:39 PM, Nathan Walker wrote:
> Currently in Java 18 we can make backwards compatible changes to the
> contents of a record.
>
> Given:
>
>     record Point(int x, int y){ }
>
> We can add point z with:
>
>     record Point(int x, int y, int z) {
>
>        @Deprecated
>        Point(int x, int y){ this(x, y, 0); }
>     }
>
> Or given:
>
>     record Point(int x, int y, int z){ }
>
> We can remove point z with:
>
>     record Point(int x, int y) {
>
>        @Deprecated
>        Point(int x, int y, int z){ this(x, y); }
>
>        @Deprecated
>        public z(){ return 0; }
>     }
>
> If they are marked serializable then even the serialized forms maintain
> backwards compatibility, with the z value in the first example being
> defaulted to 0 during deserialization, and the z in the second example
> being ignored during deserialization.
>
> But if I understood JEP 405 correctly, a record pattern depends on matching
> the exact record components.  So is there a way in JEP 405 to change a
> record's components without breaking everywhere that is using the record in
> a pattern match statement?  I would be concerned about using records in any
> public API if every minor change to a record's structure will require a new
> major version release under semantic versioning rules.
>
> Thanks for your time.


More information about the amber-dev mailing list