Розглянемо такий код:
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()));
}
}
Компіляція та запуск робіт, як очікувалося:
$ javac *.java
$ java -cp . C
[@A()]
Але тоді розгляньте це:
$ rm A.class
$ java -cp . C
[]
Я би очікував, що це кине ClassNotFoundException
, оскільки @A
відсутній. Але натомість він мовчки скидає анотацію.
Ця поведінка де-небудь задокументована в JLS, чи це химерність JVM Sun? Яке обґрунтування цього?
Це здається зручним для таких речей, як javax.annotation.Nonnull
(що, здається, все одно мало бути @Retention(CLASS)
), але для багатьох інших анотацій здається, що це може спричинити різні погані речі під час виконання.