Consider the following code:
A.java:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface A{}
C.java:
import java.util.*;
@A public class C {
public static void main(String[] args){
System.out.println(Arrays.toString(C.class.getAnnotations()));
}
}
Compiling and running works as expected:
$ javac *.java
$ java -cp . C
[@A()]
But then consider this:
$ rm A.class
$ java -cp . C
[]
I would've expected it to throw a ClassNotFoundException
, since @A
is missing. But instead, it silently drops the annotation.
Is this behaviour documented in the JLS somewhere, or is it a quirk of Sun's JVM? What's the rationale for it?
It seems convenient for things like javax.annotation.Nonnull
(which seems like it should've been @Retention(CLASS)
anyway), but for many other annotations it seems like it could cause various bad things to happen at runtime.