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).

4

1 回答 1

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
于 2021-09-04T15:38:11.437 回答