Reflection, TYPE_USE annotation on THROWS on inner class constructor, Java 9+

Michael Rasmussen Michael.Rasmussen at roguewave.com
Fri Nov 9 15:13:00 UTC 2018


Hi

When adding a TYPE_USE annotation with runtime retention to the throws exception clause of a constructor of an inner class, these annotations are not found via Constructor.getAnnotatedExceptionType().getDeclaredAnnotations() on Java 9+, but present when running on Java 8.
For static nested classes, the annotations are correctly found on Java 9+.

See sample code below.

Looking in the .class file for the nested classes (with javap), the runtime annotation is present there:
  public app1.MiscTest8$Inner(app1.MiscTest8) throws java.lang.Exception;
    (...)
    RuntimeVisibleTypeAnnotations:
      0: #17(): THROWS, type_index=0
        app1.MiscTest8$MyAnnotation

and 
  public app1.MiscTest8$StaticInner() throws java.lang.Exception;
    (...)
    RuntimeVisibleTypeAnnotations:
      0: #14(): THROWS, type_index=0
        app1.MiscTest8$MyAnnotation

When I run it on Java 8, I get the following output:
=== public app1.MiscTest8$Inner(app1.MiscTest8) throws java.lang.Exception ===
[@app1.MiscTest8$MyAnnotation()]
=== public app1.MiscTest8$StaticInner() throws java.lang.Exception ===
[@app1.MiscTest8$MyAnnotation()]
=== public static void app1.MiscTest8.main(java.lang.String[]) throws java.lang.Exception ===
[@app1.MiscTest8$MyAnnotation()]

But when I run the same class files on Java 9, 10, 11, (and 12-ea) I get:
=== public app1.MiscTest8$Inner(app1.MiscTest8) throws java.lang.Exception ===
[]
=== public app1.MiscTest8$StaticInner() throws java.lang.Exception ===
[@app1.MiscTest8$MyAnnotation()]
=== public static void app1.MiscTest8.main(java.lang.String[]) throws java.lang.Exception ===
[@app1.MiscTest8$MyAnnotation()]


Shouldn't I be able to find this annotation vis getAnnotatedExceptionTypes() on Java9+, similar to how it works on Java 8?

Kind regards
Michael Rasmussen.


/* --- snip --- */
package app1;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Executable;
import java.util.Arrays;

public class MiscTest8 {

  @Retention(value = RetentionPolicy.RUNTIME)
  @Target(ElementType.TYPE_USE)
  @interface MyAnnotation {
  }

  class Inner {
    public Inner() throws @MyAnnotation Exception {
    }
  }

  static class StaticInner {
    public StaticInner() throws @MyAnnotation Exception {
    }
  }
  public static void main(String[] args) throws @MyAnnotation Exception {
    foo(Inner.class.getDeclaredConstructor(MiscTest8.class));
    foo(StaticInner.class.getDeclaredConstructor());
    foo(MiscTest8.class.getDeclaredMethod("main", String[].class));
  }

  static void foo(Executable c) throws Exception {
    System.out.println("=== " + c + " ===");

    for (AnnotatedType exceptionType : c.getAnnotatedExceptionTypes()) {
      System.out.println(Arrays.toString(exceptionType.getDeclaredAnnotations()));
    }
  }
}
/* --- snap --- */


More information about the core-libs-dev mailing list