2

I know it's possible to get a class by name, using

public String className = "someName";
public Class<?> c = Class.forName(className);

Is it possible to retrieve an annotation by name? I tried this:

public String annotationName = "someName";
public Class<?> c = Class.forName(annotationName);

And then casting c to Class<? extends Annotation>, which works, but I get an Unchecked cast warning.

I also tried

public String annotationName = "someName";
public Class<? extends Annotation> c = Class.forName(annotationName);

But when I do that I get the error

Incompatible types.
Required: Class<? extends java.lang.annotation.Annotation>
Found: Class<Capture<?>>
Alon
  • 743
  • 10
  • 23
  • Possible duplicate of [How to get annotation class name, attribute values using reflection](https://stackoverflow.com/questions/20362493/how-to-get-annotation-class-name-attribute-values-using-reflection) – Hadi J May 12 '19 at 09:01
  • @HadiJ If I understand correctly, that question deals with trying to retrieve all annotation names. My question is if I already have a specific annotation name, how to get to the annotation – Alon May 12 '19 at 09:05
  • 1
    The first way you showed is the way to do it. You can't do anything to the unchecked cast warning except to suppress it. That's just a limitation in Java's generics. – Sweeper May 12 '19 at 09:07
  • *And then casting c to Class extends Annotation>, which works* - can't be possible, bounded types only work if they involve an interface or class – Eugene May 12 '19 at 10:01
  • @Eugene [`Annotation`](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Annotation.html) *is* an interface. – Holger May 13 '19 at 07:55
  • @Sweeper Not correct. [There is](https://stackoverflow.com/a/56107929/2711488) a type safe solution. – Holger May 13 '19 at 07:59

1 Answers1

3

Use asSubclass. Unlike compiler generated type casts, which can only work with types known at compile-time, this will perform a check against the Class object retrieved at runtime. Since this is safe, it won’t generated an “Unchecked cast” warning. Note the existence of a similar operation, cast for casting an instance of a Class. These methods were added in Java 5, specifically to aid code using Generics.

String annotationName = "java.lang.Deprecated";
Class<? extends Annotation> c = Class.forName(annotationName).asSubclass(Annotation.class);
boolean depr = Thread.class.getMethod("stop").isAnnotationPresent(c);
System.out.println(depr);
Holger
  • 285,553
  • 42
  • 434
  • 765