4 Replies Latest reply: Aug 12, 2013 12:12 PM by ErickHagstrom RSS

    Reading an ElementType.LOCAL_VARIABLE

    813950
      I have been trying read a ElementType.LOCAL_VARIABLE annotation using reflect package.
      Here is my annotation:
      @Target(value={ElementType.TYPE,ElementType.LOCAL_VARIABLE})
      @Retention(value=RetentionPolicy.RUNTIME)
      public @interface TestAnnotation{
           String theName();
      }

      Here is my program to try read the annotation:
      public class TestTheAnnotation{
           public static void main(String[] args){
                @TestAnnotation(theName="My_LastName,My_FirstName")
                Integer id=new Integer(1);
                System.out.println(">> "+id.getClass().getAnnotations().length);
                System.out.println(">> "+id.getClass().getDeclaredAnnotations().length);
           }
      }

      The methods getAnnotations, and getDeclaredAnnotations only return the annotations declared for the object, but I want the annotation declared for the local variable.
      Is there any way to do this?

      Thanks.
        • 1. Re: Reading an ElementType.LOCAL_VARIABLE
          DarrylBurke
          Cross posted
          http://www.java-forums.org/advanced-java/44053-reading-annotaion-elementtype-local_variable.html

          db
          • 2. Re: Reading an ElementType.LOCAL_VARIABLE
            baftos
            getAnnotations() and getDeclaredAnnotations() are methods that you can invoke on an object of the type java.lang.Class (it's where they are defined).
            In your code, id.getClass() is exactly such an object and it is the same as Integer.class, because id refers to an Integer object.
            Now, it seems that the Integer class has no annotations at all or no annotations with RetentionPolicy.RUNTIME.
            You annotated a local variable.
            According to http://download.oracle.com/javase/6/docs/api/index.html, there are a few classes that extend the AnnotatedElement interface (java.lang.Class among them),
            but none that corresponds to the local variable element. So, your annotation is inaccessible at run-time.
            On the other hand, check out this:
            @TestAnnotation(theName="My_LastName,My_FirstName") 
            public class TestTheAnnotation
            {
                 public static void main(String[]args) throws Exception
                 {
                      Class cl = TestTheAnnotation.class;
                      System.out.println(">> "+cl.getAnnotations().length);
                      System.out.println(">> "+cl.getDeclaredAnnotations().length);
                 }
            }
            
            @Target(value={ElementType.TYPE,ElementType.LOCAL_VARIABLE})
            @Retention(value=RetentionPolicy.RUNTIME)
            @interface TestAnnotation
            {
                 String theName();
            }
            Edit: Found this: "Local variable annotations are not retained in class files (or at runtime) regardless of the retention policy set on the annotation type. See JLS 9.6.1.2."
            Less words than me, but authoritative (from http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html).

            Edited by: baftos on May 14, 2011 12:23 PM
            • 3. Re: Reading an ElementType.LOCAL_VARIABLE
              813950
              This is the same as the following that I added:
              @TestAnnotation(theName="My_LastName,My_FirstName")
              public class TestTheAnnotation{
                   public static void main(String[] args)
                        throws Exception{
                        Class cl=TestTheAnnotation.class;
                        System.out.println(">> "+cl.getAnnotations().length);
                        System.out.println(">> "+cl.getDeclaredAnnotations().length);
                        cl=new TestTheAnnotation().getClass();
                        System.out.println(">> "+cl.getAnnotations().length);
                        System.out.println(">> "+cl.getDeclaredAnnotations().length);
                   }
              }

              @Target(value={ElementType.TYPE,
                   ElementType.LOCAL_VARIABLE})
              @Retention(value=RetentionPolicy.RUNTIME)
              @interface TestAnnotation{
                   String theName();
              }

              And is the same that I am already doing.

              Edited by: user4244892 on May 14, 2011 12:54 PM
              • 4. Re: Reading an ElementType.LOCAL_VARIABLE
                ErickHagstrom

                Unfortunately you can't do what you are trying to do. You can define the annotation, and you can apply it to a local variable target, but you can't find it through reflection because the annotation isn't stored in the classfile, See section 9.6.1.2 in the Java Language Specification 3.

                 

                JSR 308 (The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 308) addresses this. An implementation seems to be available at (Type Annotations (JSR 308) and the Checker Framework), though I haven't tried it out.