[type-annos-observers] ordering of annotated array brackets

Alex Buckley alex.buckley at oracle.com
Tue Apr 1 00:32:20 UTC 2014


The type parameter case is the first exception to the "left-to-right" 
rule that makes intuitive sense to me. In API<T>, the [] after 'ts' can 
reasonably be said to form an array type whose component type is the 
type of T, which itself may be an array type - this highlights the 
recursive flavor of array types which JSR 308 otherwise tried to avoid 
(compare ArrayType in JLS7 [1] and JLS8 [2]).

Since javac, ecj, and OpenJDK's Core Reflection all treat 
post-identifier [] in a variable declaration as the outermost dimensions 
of an array type, and since it would be a significant engineering 
exercise to change that, and since method declarations appear to work 
the same way [3], I will modify JLS8 to agree.

Alex

[1] http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.3
[2] http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.3
[3] I augmented Markus' program from the first mail in this thread:

   private @A int @B [] m() @C [] { return null; }
   ...
   printMethod("m");
   ...
   private static void printMethod(String name)
     throws NoSuchMethodException {
       System.out.printf("%-12s %s\n",
         name + ":",
         toString(Snippet.class.
                  getDeclaredMethod(name, new Class<?>[]{}).
                  getAnnotatedReturnType()));
   }

On 3/27/2014 8:12 AM, Markus Keller wrote:
> Alex Buckley <alex.buckley at oracle.com> wrote on 2014-03-19 19:33:43:
>> I understand the a2[0]=a1 scenario. Since making it well-typed means
>> redefining the array type construction rule to consider post-identifier
>> [] first, I am happy for a2[0]=a1 to not be well typed. There is a
>> simple fix here: declare a1 and a2 in different declarations.
>
> Wasn't it a no-go in the past to require users to rewrite existing code?
> http://mail.openjdk.java.net/pipermail/type-annotations-spec-observers/2013-January/000064.html
>
> Not adding new features to deprecated constructs would have been fine, but
> adding them in an inconsistent way is really bad.
>
> The too simple "left-to-right" rule also makes simple refactorings a pain,
> e.g. replacing a type parameter by a concrete type:
>
> import static java.lang.annotation.ElementType.TYPE_USE;
> import java.lang.annotation.*;
>
> @Target(TYPE_USE)
> @interface NonEmpty {}
>
> public class Test {
>      public API<String @NonEmpty []> api;
>      public API2 api2;
>
>      void test() {
>          api.t = api.ts[0]; // OK
>          api2.t = api2.ts[0]; // Not OK?
>      }
> }
>
> class API<T> {
>      public T t, ts[];
>      void assign() {
>          t = ts[0]; // OK
>      }
> }
>
> class API2 {
>      public String @NonEmpty [] t, ts[];
>      void assign() {
>          t = ts[0]; // Not OK?
>      }
> }
>


More information about the type-annotations-spec-observers mailing list