ordering of annotated array brackets
Markus Keller
markus_keller at ch.ibm.com
Mon Mar 3 16:29:42 UTC 2014
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-comments
mailing list