ordering of annotated array brackets
Alex Buckley
alex.buckley at oracle.com
Tue Apr 1 00:45:40 UTC 2014
Per the thread on the observer list [1], I have filed
https://bugs.openjdk.java.net/browse/JDK-8038881 to modify the JLS.
It is instructive to compare the informal text in the old JSR 308 spec
(commented out in September 2011) with the actual JLS text needed to
effect the desired language design.
Alex
[1]
http://mail.openjdk.java.net/pipermail/type-annotations-spec-observers/2014-April/000289.html
On 3/3/2014 11:51 AM, Alex Buckley wrote:
> Hi Markus,
>
> Thanks for your mail and excellent test case.
>
> However, I don't see why the post-identifier "@C []" should be the
> outermost dimension, as if "int @C [] @B []" had been written. Certainly
> there was no hint of this in the January 2013 thread "Annotations on
> extended dimension in method declarations".
>
> I think the "followed by ..." wording of 10.2 indicates that "@C []"
> should be the innermost (deepest) dimension, as if "int @B [] @C []" had
> been written.
>
> I am not clear if javac or java.lang.reflect is assembling the full
> array type in (what I consider to be) the wrong order. Werner, if you're
> reading this, can you help us out?
>
> Alex
>
> On 3/3/2014 8:29 AM, Markus Keller wrote:
>> JLS8 10.2 says:
>> "In a variable declaration (§8.3, §8.4.1, §9.3, §14.14, §14.20) except
>> for
>> a variable
>> arity parameter, the array type of a variable is denoted by the array
>> type
>> that appears
>> at the beginning of the declaration, followed by any bracket pairs that
>> follow the
>> variable's Identifier in the declarator."
>>
>> This was fine for Java < 8, where array dimension brackets were
>> indistinguishable. But with type annotations, the order of annotated
>> dimension brackets matters.
>>
>> Example: private @A int @B [] field @C [];
>>
>> In "1.8.0-b129", reflection says the type of "field" is "@A int @C [] @B
>> []", and that totally makes sense. See also [1].
>>
>> The paragraph should e.g. say:
>> "[..] the array type of a variable is denoted by the element type at the
>> beginning of the declaration, followed by any (potentially annotated)
>> bracket pairs that follow the variable's Identifier in the declarator,
>> followed by any (potentially annotated) bracket pairs of the array
>> type at
>> the beginning of the declaration."
>>
>> The ordering of consecutive array dimension brackets is currently also
>> undefined by the spec. There's just an informal example in 9.7.4
>> (which is
>> good; it's just not a spec).
>>
>> Regards,
>> Markus
>>
>>
>> [1] Executable snippet to test reflection:
>>
>> import java.lang.annotation.*;
>> import java.lang.reflect.*;
>> import java.util.stream.*;
>>
>> @Target(ElementType.TYPE_USE) @Retention(RetentionPolicy.RUNTIME)
>> @interface A {}
>> @Target(ElementType.TYPE_USE) @Retention(RetentionPolicy.RUNTIME)
>> @interface B {}
>> @Target(ElementType.TYPE_USE) @Retention(RetentionPolicy.RUNTIME)
>> @interface C {}
>>
>> public class Snippet {
>> private @A int @B [] field @C [];
>> private @A int @C [] @B [] fieldNormal;
>> private @A int @B [] fieldBase, fieldExtra @C [];
>>
>> public static void main(String[] args) throws Exception {
>> printField("field");
>> printField("fieldNormal");
>> printField("fieldBase");
>> printField("fieldExtra");
>> }
>>
>> private static void printField(String name) throws
>> NoSuchFieldException {
>> System.out.printf("%-12s %s\n", name + ":",
>> toString(Snippet.class.getDeclaredField(name).getAnnotatedType()));
>> }
>>
>> private static String toString(AnnotatedType annotatedType) {
>> StringBuilder sb = new StringBuilder();
>> while (annotatedType instanceof AnnotatedArrayType) {
>> sb.append("
>> ").append(toString(annotatedType.getAnnotations())).append("[]");
>> annotatedType = ((AnnotatedArrayType)
>> annotatedType).getAnnotatedGenericComponentType();
>> }
>> Type type = annotatedType.getType();
>> sb.insert(0, type.toString());
>> sb.insert(0, toString(annotatedType.getAnnotations()));
>> return sb.toString();
>> }
>>
>> private static String toString(Annotation[] annotations) {
>> return Stream.of(annotations).map(Snippet::toSimpleString).
>> collect(Collectors.joining(" ", "", " "));
>> }
>>
>> public static String toSimpleString(Annotation a) {
>> return "@" + a.annotationType().getSimpleName();
>> }
>> }
>>
More information about the type-annotations-spec-experts
mailing list