Annotation element values

Alex Buckley alex.buckley at oracle.com
Mon Jan 6 10:55:38 PST 2014


Mohan,

The Java Tutorial rarely goes into any depth about how to use reflection 
APIs like the Language Model API. The javadoc is quite extensive.

In processEnclosedElements, you're calling e.getAnnotationMirrors which 
returns the mirror for the @TypeUses(...) container annotation. If you 
want @TypeUse(0) and @TypeUse(1) immediately, call 
e.getAnnotationsByType instead. Everything is working as designed.

In processClassTypeParameters, we might have a bug. You've definitely 
got a mirror for the bound Integer, but typeMirror.getAnnotationsByType 
isn't revealing @TypeUse(2) or @TypeUse(3), which it should.

Joel, Eric,

I recall there were problems in b111 or thereabouts with annotations on 
type parameters and their bounds. Was that fixed or is it still open?

Alex

On 1/4/2014 4:08 AM, Mohan Radhakrishnan wrote:
> I was mislead by a wrong jdk 8 version.
>
> It compiles and runs using b120 but I will show the actual code. I was
> reading
> http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
> but the documentation seemed to be sketchy. The code had to be written
> like this. The IDE showed there are some rules like the requirement for
> both annotations to have the same retention policy.
>
> import java.lang.annotation.*;
>
> public class RepeatableAnnotation {
>
>      @Retention(RetentionPolicy.RUNTIME)
>      @Target(ElementType.TYPE_USE)
>      public @interface TypeUses {
>          TypeUse[] value();
>      }
>
>      @Retention(RetentionPolicy.RUNTIME)
>      @Target(ElementType.TYPE_USE)
>      @Repeatable(TypeUses.class)
>      protected @interface  TypeUse {
>          int value();
>      }
>
>      @TypeUse(value = 0) @TypeUse(value = 1)class Test1< T extends
> @TypeUse(value = 2) @TypeUse(value = 3) Integer> {
>
>          /**
>           * A type annotation is permitted in front of a constructor
> declaration, where declaration annotations are already
>           permitted.
>           */
>          @TypeUse(value = 0) <S> Test1(String s){
>
>          }
>      }
>
> }
>
> -----------Processor-------------
>
>      private void processEnclosedElements(List<? extends Element>
> enclosedElements,
>                                           RoundEnvironment roundEnv) {
>
>          for( Element e : enclosedElements ){
>
>              if (e.getKind() == ElementKind.CLASS){
>
>                  System.out.println( "Annotation [" +
> e.getAnnotationMirrors() + "] [" + e  + "]");
>
>                  for( AnnotationMirror typeMirror :
> e.getAnnotationMirrors())  {
>
>                      for(Map.Entry< ? extends ExecutableElement, ?
> extends AnnotationValue> m : typeMirror.getElementValues().entrySet()){
>
>                          System.out.println( "[" + m.getKey() +"][" +
> m.getValue() + "]");
>
>                      }
>
>                  }
>                  processClassTypeParameters(e);
>
>              }
>          }
>      }
>
>      private void processClassTypeParameters(Element e) {
>
>          for (TypeParameterElement typeParameterElement : ((TypeElement)
> e).getTypeParameters()) {
>
>              for (TypeMirror typeMirror :
> typeParameterElement.getBounds()) {
>
>                  System.out.println( "Annotation [" +
> Arrays.asList(typeMirror.getAnnotationsByType(RepeatableAnnotation.TypeUse.class))
> + "] [" + typeMirror  + "]");
>
>              }
>          }
>      }
>
> ----------Result-------------
>
> Annotation
> [@com.test.RepeatableAnnotation.TypeUses({@com.test.RepeatableAnnotation.TypeUse(0),
> @com.test.RepeatableAnnotation.TypeUse(1)})]
> [com.test.RepeatableAnnotation.Test1]
> [value()][{@com.test.RepeatableAnnotation.TypeUse(0),
> @com.test.RepeatableAnnotation.TypeUse(1)}]
> Annotation [[]] [java.lang.Integer]
>
> I was trying to
>
> 1. get the value '0' or '1' in the method 'processEnclosedElements'
> 2. get the Annotation applied on the bounds. Now an empty List is printed.
>
> Thanks,
> Mohan
>
>
> On Sat, Jan 4, 2014 at 12:24 AM, Alex Buckley <alex.buckley at oracle.com
> <mailto:alex.buckley at oracle.com>> wrote:
>
>     On 12/24/2013 4:53 AM, Mohan Radhakrishnan wrote:
>
>         Tried to subscribe using
>         http://mail.openjdk.java.net/__mailman/listinfo/type-__annotations-dev
>         <http://mail.openjdk.java.net/mailman/listinfo/type-annotations-dev>
>
>
>     Your confirmation mail (the one you send in response to the
>     challenge) was received by the list, but for some reason it was not
>     processed. I have subscribed you by hand - you should have received
>     a welcome mail.
>
>
>         I could compile the processor code with b113. But with b120 it
>         doesn't.
>
>
>     Please be more specific. The code below compiled with b113 but does
>     not compile with b120? What compile-time error is given?
>
>
>         Is this code supposed to print the annotation element values ? I
>         am also
>         trying to get the annotations applied on the bound 'Integer'.
>
>
>     You are calling typeParameterElement.__getAnnotationMirrors(), which
>     returns annotations that are directly present on the element. But
>     the element - the declaration of a type parameter called T - is
>     completely unannotated, so there are no element values to print out.
>
>     As for the bound Integer, you are calling
>     typeMirror.__getAnnotationsByType(...) in the right way. I would
>     expect to see @TypeUse(2) and @TypeUse(3) in the output.
>
>     Alex
>
>
>         --------------Source----------__----
>              @TypeUse(value = 0) @TypeUse(value = 1)class Test1< T extends
>         @TypeUse(value = 2) @TypeUse(value = 3) Integer> {
>
>                   /**
>                    * A type annotation is permitted in front of a
>         constructor
>         declaration, where declaration annotations are already
>                    permitted.
>                    */
>                   @TypeUse(value = 0) <S> Test1(String s){
>
>                   }
>               }
>
>         }
>
>         --------------------Processor code--------------------------__-
>
>         for (TypeParameterElement typeParameterElement : ((TypeElement)
>         e).getTypeParameters()) {
>
>                       for( AnnotationMirror am  :
>         typeParameterElement.__getAnnotationMirrors() ){
>
>                           System.out.println( "Annotation [" + am + "] [" +
>         typeParameterElement  + "]");
>
>                           for(Map.Entry< ? extends ExecutableElement, ?
>         extends
>         AnnotationValue> m : am.getElementValues().__entrySet()){
>
>                               System.out.println( "[" + m.getKey() +"][" +
>         m.getValue() + "]");
>
>                           }
>
>                       }
>
>                       for (TypeMirror typeMirror :
>         typeParameterElement.__getBounds()) {
>
>                           System.out.println( "Annotation [" +
>         Arrays.asList(typeMirror.__getAnnotationsByType(__RepeatableAnnotation.TypeUse.__class))
>         + "] [" + typeMirror  + "]");
>
>                       }
>                   }
>               }
>
>         Thanks.
>
>


More information about the type-annotations-dev mailing list