[type-annos-observers] annotated type of array-typed varargs parameter
Markus Keller
markus_keller at ch.ibm.com
Sun Apr 6 19:43:30 UTC 2014
Hi Alex
Thanks for the clarification.
8.4.1 also defines: "a variable arity parameter, indicated by an ellipsis
following the type." Strictly speaking, it should be "indicated by a
(possibly annotated) ellipsis following the type".
Using 10.2 to hold the definition of a variable's type sounds good. The
final text should also tell that annotations belong to the bracket pair or
ellipsis that follows them, so that it's clear that the annotations are
reason for the explicit specification of the order of the array
dimensions.
Markus
"type-annotations-spec-observers"
<type-annotations-spec-observers-bounces at openjdk.java.net> wrote on
2014-04-04 21:04:39:
> From: Alex Buckley <alex.buckley at oracle.com>
> To: type-annotations-spec-experts
<type-annotations-spec-experts at openjdk.java.net>
> Date: 2014-04-04 21:04
> Subject: Re: [type-annos-observers] annotated type of array-typed
varargs parameter
> Sent by: "type-annotations-spec-observers"
<type-annotations-spec-observers-bounces at openjdk.java.net>
>
> Hi Markus,
>
> I think it's pretty clear that the "intuitive order" is desirable, for
> two reasons:
>
> 1) It should be possible to refactor pArr's type to match pVar's type by
> replacing the final [] with '...', and not change the array type of
> pVar. That is, the following method call (in someone else's code, so
> can't be easily changed) should keep working after the refactoring:
>
> var(new Object @A [] {});
>
> 2) I see this more as a spec issue than a true design issue. Formerly,
> the array type was specified in recursive fashion, building on the
> component type ("the component type is the UnannType"). That's why, for
> a variable arity parameter, it looked like the compiler was constructing
> an array of type Object @B [] @A []. But we've generally come to specify
> array types in a linear fashion, which would mean the compiler is deemed
> to construct an array of type Object @A [] @B [] (or Object @A [] if you
> omit later dimensions, as in method call above).
>
> With reference to JDK-8038881, I'd propose to have 8.4.1 always point to
> 10.2 for a variable arity parameter, and for 10.2 to build up the
> parameter's type in basically the same fashion as for other array types
> [excluding post-identifier [], of course, since they're not legal here].
>
> Happily, JLS 15.12.2 which considers variable arity parameters speaks
> only of the full array type T[] which is the type of the last parameter.
> So that is unaffected by clarifications to 8.4.1 / 10.2, as long as
> 8.4.1 / 10.2 are deterministic about the outermost dimension.
>
> Alex
>
> On 4/4/2014 7:14 AM, Markus Keller wrote:
> > We've found a problem with the definition of the varargs syntax on
array
> > types. The methods "var" and "arr" below should intuitively have the
same
> > formal parameter type "Object @A [] @B []", but that clashes with the
> > order of annotations on array dimensions:
> >
> > interface Test {
> > void var(Object @A [] @B ... pVar);
> > void arr(Object @A [] @B [] pArr);
> > }
> > @Target(ElementType.TYPE_USE) @interface A { }
> > @Target(ElementType.TYPE_USE) @interface B { }
> >
> > The clarification for 8.4.1 in
> > https://bugs.openjdk.java.net/browse/JDK-8038881 says: "If the formal
> > parameter is a variable arity parameter, then the declared type is an
> > array type whose component type is UnannType."
> >
> > In "var", the UnannType is "Object @A []", so the type of the
parameter is
> > actually "Object @B [] @A []", according to the annotation order given
in
> > 9.7.4.
> >
> > In JDK 1.8.0-b132, reflection uses the intuitive order. The snippet
below
> > prints:
> >
> > var: class java.lang.Object @A [] @B []
> > arr: class java.lang.Object @A [] @B []
> >
> > That's incorrect according to JLS8. java-annotation-design.html
doesn't
> > address this problem (just says "The varargs syntax “...” is treated
> > analogously to array brackets").
> >
> > I don't see a good solution.
> > a) Say JLS8 is right. => We lose the simple transformation that turns
a
> > vararg into a normal array dimension by changing ... into [].
> > b) Say the above transformation must be valid. => The annotation in
front
> > of the ... no longer applies to the outermost array type, which is
also
> > strange, because that's the array that is constructed by the compiler
for
> > a variable arity method invocation.
> >
> >
> >
> > 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 {}
> >
> > public class Snippet {
> > void var(Object @A [] @B ... pVar) { }
> > void arr(Object @A [] @B [] pArr) { }
> >
> > public static void main(String[] args) throws Exception {
> > printParamType(Snippet.class.getDeclaredMethod("var",
> > Object[][].class));
> > printParamType(Snippet.class.getDeclaredMethod("arr",
> > Object[][].class));
> > }
> >
> > private static void printParamType(Method method) {
> > System.out.printf("%-5s %s\n", method.getName() + ":",
> > toString(method.getAnnotatedParameterTypes()[0]));
> > }
> >
> > 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();
> > }
> > }
> >
> > Markus
> >
>
More information about the type-annotations-spec-observers
mailing list