22

I was previously using this contrived code

record Foo(int bar[]) {}

which is making use of the C-style array-notation. And it compiled fine in Java 15.

Now, all of the sudden, with the official release of records in Java 16, it does not compile anymore. Here is the output from jshell:

jshell> record Foo(int bar[]) {}
|  Error:
|  legacy array notation not allowed on record components
|  record Foo(int bar[]) {}
|                    ^

Why did it compile in Java 15, was this a bug? Out of curiousity, why is it not supported in records, while being supported anywhere else in Java?

I am using javac from Adoptium (based on OpenJDK).

Naman
  • 27,789
  • 26
  • 218
  • 353
Zabuzard
  • 25,064
  • 8
  • 58
  • 82

1 Answers1

31

Explanation

The C-style array notation is considered legacy and it seems that they are trying to fade it out when possible on new constructs (it can not be changed retrofitting on old constructs to not drop backwards compatibility).

You would have to ask an actual developer for the precise reasoning behind this decision.


Bug

The fact that it worked in Java 15 is indeed a bug. The specifications actually did not allow it, even for Java 15, but this was overlooked and javac accidentally supported it.

They noticed it and fixed it for Java 16, hence it does not compile anymore.

You can read more about it here:


JLS definition

The section in the JLS that does not allow the notation can be found at JLS §8.10.1, where it defines the syntax of RecordComponents as:

RecordComponent:
  {RecordComponentModifier} UnannType Identifier
  VariableArityRecordComponent 

with

VariableArityRecordComponent:
  {RecordComponentModifier} UnannType {Annotation} ... Identifier

and

RecordComponentModifier:
  Annotation
Zabuzard
  • 25,064
  • 8
  • 58
  • 82
  • 3
    Probably reused a snippet of parser definition from everywhere else before realizing they needed a copy-and-paste edit. – chrylis -cautiouslyoptimistic- Sep 05 '21 at 01:07
  • 8
    This explanation is accurate; the C-style array notation is considered legacy and is not being carried forward into new constructs. We confronted this earlier when we did Local Variable Type Inference; C-style arrays would have complicated the feature for little benefit (e.g., `var x[] = ...`). Trying to phase it out fully is likely more disruption than it is worth. – Brian Goetz Sep 05 '21 at 14:53
  • 1
    @BrianGoetz considering the millions of places in the JDK code itself, where this legacy syntax has been used, it would indeed be very disruptive. On the other hand, being forced to go through the code bears the chances to notice lots of the other WTFs in that code… – Holger Sep 06 '21 at 09:46