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