Since JDK 1.6, its JavaC comes with standardized API for compile time processing of Annotations. Just by writing and registering a Processor in a JAR file of the API containing also the Annotations, one can effectively extend the compile time semantics of the Java language. By hooking into the compilation process of everyone using the JAR library, one can analyse all the Annotations usages, process them and generate additional files that can be then consumed during runtime.
NetBeans uses this style to convert nicely looking Annotations into a bit messy, yet powerful, layer XML file systems. This feature is available since version 6.7 released in 2009. Get more details about CompileTimeCaches!
There are very interesting aspects for BackwardCompatibility. By having own processor code running during compilation, one can keep own annotation unchanged across multiple releases, yet each of the new releases can generate something different during the compilation. As a result, one can deliver performance improvements, or even slightly shift mean of the API just by letting people compile their applications against new version of own libraries.