A Program Annotation Facility for the Javatm Programming Language

JSR-175 Public Draft Specification



I. Introduction

This document describes a simple program annotation facility for the Java programming language. This facility allows developers to define custom annotation types and to annotate fields, methods, classes, and other program elements with annotations corresponding to these types. These annotations do not directly affect the semantics of a program. Development and deployment tools can, however, read these annotations and process them in some fashion, perhaps producing additional Java programming language source files, XML documents, or other artifacts to be used in conjunction with the program containing the annotations. For example, a tool called a stub generator could generate remote procedure call stubs as directed by annotations indicating which methods were designed for remote use.

As another example of the sort of thing one could do with annotations, consider the familiar @deprecated tag. This tag does not affect the behavior of deprecated elements, but tells the compiler to emit warnings when annotated elements are used. The Javadoc tool also uses these annotations to generate appropriate documentation of the deprecated status of API elements. The deprecation facility was implemented in an ad hoc fashion using documentation comments, but could have been implemented atop a program annotation facility, had one existed at the time the deprecation facility was designed.

A second example of ad hoc program annotation already present in the Java platform is the transient modifier. The presence or absence of this modifier does not affect the semantics of a field, but it may be queried at runtime by the libraries that comprise the serialization subsystem as part of the serialization process. It is also queried at documentation generation time by the Javadoc utility as part of the process of generating documentation for the serialized form of the class.

Since many annotations will be used only by development tools such as stub generators, it makes little sense to retain all annotations at run time; doing so could increase run-time memory-footprint and harm performance. There are, however, some annotation types that are useful at run time, and some that are useful in tools that only have access to class files (not source files). Therefore, certain annotations are stored by the compiler in class file attributes (JVMS 4.7), and some of these annotations are then made available for inspection at runtime via new reflective APIs.

The program annotation facility consists of several parts:

  1. A syntax for declaring annotation types
  2. A syntax for annotating program elements
  3. A set of standard meta-annotation types for specifying the use of annotation types (and one additional standard annotation type)
  4. An API for reading annotations
  5. Library Support for Annotations
  6. A specification for how annotations are recorded by compilers in class file attributes

II. Declaring Annotation Types

Every annotation has an annotation type associated with it. In order to create an annotation type, you must declare it with an annotation type declaration. In addition to enabling a family of annotations, declaring an annotation type creates an interface that can be used to read those annotations. Annotation types can also be used in the definition of other annotation types, giving rise to annotation types with deep structure, and allowing substructures to be reused. Annotation types share the same namespace as ordinary class and interface types.

An annotation type declaration takes the form of a highly restricted interface declaration. Annotation type declarations are legal wherever interface declarations are legal, and have the same scope and accessibility. To distinguish an annotation type declaration from an ordinary interface declaration, the keyword interface is replaced by @interface. Note that the at sign (@) and the keyword interface are two distinct tokens; technically it is possible to separate them with whitespace, but convention dictates that this is not done.

The following restrictions are imposed on annotation type declarations:

  1. No extends clause is permitted. (Annotation types automatically extend a new marker interface, java.lang.annotation.Annotation.)
  2. Methods must not have any parameters.
  3. Methods must not have any type parameters (in other words, generic methods are prohibited).
  4. Method return types are restricted to primitive types, String, Class, enum types, annotation types, and arrays of the preceding types.
  5. No throws clause is permitted.
  6. Annotation types must not be parameterized.
Each method declaration in an annotation type declaration defines a member of the annotation type. Annotation types can have zero or more members. Annotation types must not contain members of the same annotation type, either directly or indirectly. In other words, this is illegal:
// Illegal self-reference!!
@interface SelfRef {
    SelfRef value();
}
and so is this:
// Illegal circularity!!
@interface Ping {
    Pong value();
}

@interface Pong {
    Ping value();
}

The interface created by an annotation type declaration inherits several additional members from java.lang.annotation.Annotation, which are the implicitly declared methods corresponding to the instance methods java.lang.Object (JLS 9.2). These methods are not, however, considered to be members of the annotation type, and it is illegal to use them in annotations.

Unlike method declarations in ordinary interfaces, a default value may be specified for an annotation type member. This is done by following its (empty) parameter list with the keyword default and the default value of the member. Note that defaults are applied dynamically at the time annotations are read; default values are not compiled into annotations. Thus, changing a default value affects annotations even in classes that were compiled before the change was made (presuming these annotations lack an explicit value for the defaulted member).

The grammar for an annotation type declaration is shown below:

    AnnotationTypeDeclaration:
        InterfaceModifiersopt @ interface Identifier AnnotationTypeBody

    AnnotationTypeBody:
        { AnnotationTypeMemberDeclarationsopt }

    AnnotationTypeMemberDeclarations:
	AnnotationTypeMemberDeclaration
	AnnotationTypeMemberDeclarations AnnotationTypeMemberDeclaration

    AnnotationTypeMemberDeclaration:
        AbstractMethodModifiersopt Type Identifier ( ) DefaultValueopt ;
        ConstantDeclaration
        ClassDeclaration
        InterfaceDeclaration
        EnumDeclaration
        AnnotationTypeDeclaration
        ;

    DefaultValue:
        default MemberValue
All of the same restrictions apply to InterfaceModifiers and AbstractMethodModifiers as apply for ordinary interface declarations. (By convention, no AbstractMethodModifiers should be present.) The Type is restricted to primitive types, String, Class, enum types, annotation types, and arrays of the preceding types. It is permissible to use bounded wildcards to parameterize the Class return type, and the compiler must enforce such bounds on annotations. (See the JSR-14 specification for a description of bounded wildcards.) Note that this does not conflict with the prohibition on generic methods, as wildcards eliminate the need for an explicit type parameter.

A MemberValue is used to specify a default value, whose type must be appropriate for the member whose default is being specified. The detailed grammar and semantic restrictions on MemberValue are contained in Section III, below.

Examples

The following annotation type declaration defines an annotation type with several members:

// Normal annotation type declaration with several members

/**
 * Describes the "request-for-enhancement" (RFE) that led to the presence of 
 * the annotated API element.
 */
public @interface RequestForEnhancement {
    int    id();        // Unique ID number associated with RFE
    String synopsis();  // Synopsis of RFE
    String engineer();  // Name of engineer who implemented RFE
    String date();      // Date RFE was implemented
}
The following annotation type declaration defines an annotation type with no members, termed a marker annotation type:
// Marker annotation type declaration

/**
 * Annotation with this type indicates that the specification of the
 * annotated API element is preliminary and subject to change.
 */
public @interface Preliminary { }
By convention, the name of the sole member in a single-member annotation type is value. (Linguistic support for this convention is provided by the single member annotation construct; you must obey the convention in order to make use of the construct.) The convention is illustrated in the following annotation type declaration:
// Single-member annotation type declaration

/**
 * Associates a copyright notice with the annotated API element.
 */
public @interface Copyright {
    String value();
}
The following annotation type declaration defines a single-member annotation type whose sole member has an array type:
// Single-member annotation type declaration with array-typed member

/**
 * Associates a list of endorsers with the annotated class.
 */
public @interface Endorsers {
    String[] value();
}
Here is an example of complex annotation types, annotation types that contain one or more members whose types are also annotation types.
// Complex Annotation Type

/**
 * A person's name.  This annotation type is not designed to be used
 * directly to annotate program elements, but to define members
 * of other annotation types.
 */
public @interface Name {
    String first();
    String last();
}

/**
 * Indicates the author of the annotated program element.
 */
public @interface Author {
    Name value();
}

/**
 * Indicates the reviewer of the annotated program element.
 */
public @interface Reviewer {
    Name value();
}

The following annotation type declaration provides default values for two of its four members:

// Annotation type declaration with defaults on some members
public @interface RequestForEnhancement {
    int    id();       // No default - must be specified in each annotation
    String synopsis(); // No default - must be specified in each annotation
    String engineer()  default "[unassigned]";
    String date()      default "[unimplemented]";

}

The following annotation type declaration shows a Class annotation whose value is restricted by a bounded wildcard.

// Annotation type declaration with bounded wildcard to restrict Class annotation
/**
 * The annotation type declaration below presumes the existence of this interface,
 * which describes a formatter for Java programming language source code.
 */
public interface Formatter { ... }

/**
 * Designates a formatter to pretty-print the annotated class.
 */
public @interface PrettyPrinter {
    Class<? extends Formatter> value();
}

III. Annotations

An annotation is a new kind of modifier containing an annotation type (as defined in the previous section) and zero or more member-value pairs, each of which associates a value with a different member of the annotation type. Annotations must contain a member-value pair for every member of the corresponding annotation type, except for those members with default values. Annotations may, but are not required to, contain member-value pairs for members with default values. The purpose of an annotation is simply to associate information with the annotated program element.

Annotations may be used as modifiers in any declaration, whether class, interface, field, method, parameter, constructor, enum, or local variable. Annotations may also be used on enum constants (which are implicit field declarations). Such annotations are placed immediately before the enum constant they annotate.

Finally, annotations may be used on package declarations, with the restriction that at most one annotated package declaration is permitted for a given package. The manner in which this restriction is enforced must, of necessity, vary from implementation to implementation. The following scheme is strongly recommended for file-system-based implementations: The sole annotated package declaration, if it exists, is placed in a source file called "package-info.java" in the directory containing the source files for the package. This file does not contain the source for a class called package-info.java; indeed it would be illegal for it to do so, as package-info is not a legal identifier. Typically "package-info.java" contains only a package declaration, preceded immediately by the annotations on the package. While the file could technically contain the source code for one or more package-private classes, it would be very bad form.

It is recommended that package-info.java, if it is present, take the place of package.html for javadoc and other similar documentation generation systems. If this file is present, the documentation generation tool should ignore package.html and look instead for the package documentation comment immediately preceding the (possibly annotated) package declaration in package-info.java. In this way, package-info.java becomes the sole repository for package level annotations and documentation. If, in future, it becomes desirable to add any other package-level information, this file should prove a convenient home for this information.

The annotation type (interface) corresponding to an annotation must be accessible at the point where the annotation is used. A declaration cannot have multiple annotations for the same annotation type. Annotations are conventionally placed before all other modifiers, but this is not a requirement; they may be freely intermixed with other modifiers.

There are three kinds of annotations. The first (normal annotation) is fully general. The others (marker annotation and single-member annotation) are merely shorthands.

    Annotation:
        NormalAnnotation
        MarkerAnnotation
        SingleMemberAnnotation
A normal annotation is used to annotate a program element:
    NormalAnnotation:
        @ TypeName ( MemberValuePairsopt )

    MemberValuePairs:
        MemberValuePair
        MemberValuePairs , MemberValuePair

    MemberValuePair:
        SimpleName = MemberValue

    MemberValue:
        ConditionalExpression
        Annotation
        MemberValueArrayInitializer

    MemberValueArrayInitializer:
        { MemberValuesopt ,opt }

    MemberValues:
        MemberValue
        MemberValues , MemberValue

Note that the at-sign (@) is a token unto itself. Technically it is possible to put whitespace in between the at-sign and the TypeName, but convention dictates that this is not done.

TypeName may be a fully qualified or simple annotation type name. A simple name may be used to refer to an annotation type defined in another package if it is imported, either singly:

    import PackageName.SimpleName;
or on demand:
    import PackageName.*;
These are normal import declarations (JLS 7.5.1, 7.5.2): annotation types are imported in the same fashion as classes and interfaces. Any annotation types defined in java.lang would be implicitly imported on demand.

The SimpleName in a MemberValuePair must be the name of one of the members of the annotation type identified by Name in the containing annotation. (In other words, the simple name in a member-value pair must also be a method name in the interface identified by Name.) The return type of this method defines the member type of the member-value pair.

If the member type is not an annotation type or an array type, MemberValue must be a ConditionalExpression (JLS 15.25) whose type is assignment compatible (JLS 5.2) with the member type. (A ConditionalExprression is simply an expression without assignments, and not necessarily an expression involving the conditional operator (? :).) If member type is a primitive type or String, the ConditionalExpression must be a constant expression (JLS 15.28). If the member type is Class, the value must be a class literal (JLS 15.8.2). If the member type is an enum type, the value must be the simple (unqualified) name of an enum constant. Loosely speaking, no matter what the member type, the value must be a compile-time constant. Note that null is not a legal member value for any member type.

If the member type is an annotation type, the MemberValue must be an Annotation with the same type.

If the member type is an array type, the MemberValue may be either a MemberValueArrayInitializer or a MemberValue that is legal for the array's element type (as defined above). A MemberValueArrayInitializer is similar to a normal array initializer (JLS 10.6), except that annotations are permitted in place of expressions. Each MemberValueInitializer (analogous to a variable initializer in an array initializer) must be a legal MemberValue for the array's element type (as defined above).

If the member type is an array type and the corresponding MemberValue is not a MemberValueArrayInitializer, an array value whose sole element is the value represented by the MemberValue is associated with the member. In other words, it is permissible to omit the curly braces when a single-element array is to be associated with an array-valued annotation type member.

Note that the array's element type cannot be an array type, that is, nested array types are not permitted as member types. (While the annotation syntax would permit this, the annotation type declaration syntax would not.)

Note that it is possible to annotate an annotation type declaration. Such annotations are known as meta-annotations. An annotation type may be used to annotate its own declaration. More generally, circularities in the transitive closure of the "annotates" relation are permitted. For example, it is legal to annotate an annotation type declaration with another annotation type, and to annotate the latter type's declaration with the former type. (The standard meta-annotation types contain several such circularities.)

Here is an example of a normal annotation:

// Normal annotation
@RequestForEnhancement(
    id       = 2868724,
    synopsis = "Provide time-travel functionality",
    engineer = "Mr. Peabody",
    date     = "4/1/2004"
)
public static void travelThroughTime(Date destination) { ... }
Note that the types of the annotations in the examples in this section are the annotation types defined in the examples in Section II.

The second form of annotation, marker annotation, is a shorthand designed for use with marker annotation types:

    MarkerAnnotation:
        @ TypeName
It is simply a shorthand for the normal annotation:
        @TypeName()
Example:
// Marker annotation
@Preliminary public class TimeTravel { ... }
Note that it is legal to use marker annotations for annotation types with members, so long as all the members have default values.

The third form of annotation, single-member annotation, is a shorthand designed for use with single-member annotation types:

    SingleMemberAnnotation:
        @ TypeName ( MemberValue )
It is shorthand for the normal annotation:
        @TypeName ( value = MemberValue )
Example:
// Single-member annotation
@Copyright("2002 Yoyodyne Propulsion Systems, Inc., All rights reserved.")
public class OscillationOverthruster { ... }
Example with array-valued single-member annotation:
// Array-valued single-member annotation
@Endorsers({"Children", "Unscrupulous dentists"})
public class Lollipop { ... }
Example with single-element array-valued single-member annotation (note that the curly braces are omitted):
// Single-element array-valued single-member annotation
@Endorsers("Epicurus")
public class Pleasure { ... }
Example with complex annotation:
// Single-member complex annotation
@Author(@Name(first = "Joe", last = "Hacker"))
public class BitTwiddle { ... }
Note that it is legal to use single-member annotations for annotation types with multiple members, so long as one member is named value, and all other members have default values.

Here is an example of an annotation that takes advantage of default values:

// Normal annotation with default values
@RequestForEnhancement(
    id       = 4561414,
    synopsis = "Balance the federal budget"
)
public static void balanceFederalBudget() {
    throw new UnsupportedOperationException("Not implemented");
}

Here is an example of an annotation with a Class member whose value is restricted by the use of a bounded wildcard.

// Single-member annotation with Class member restricted by bounded wildcard
// The annotation presumes the existence of this class.
class GorgeousFormatter implements Formatter { ... }

@PrettyPrinter(GorgeousFormatter.class)
public class Petunia { ... }

// This annotation is illegal, as String is not a subtype of Formatter!!
@PrettyPrinter(String.class) public class Begonia { ... }

IV. Standard Meta-Annotation Types

Annotation types designed for annotating annotation type declarations are called meta-annotation types. Several are provided in java.lang.annotation. Some of these meta-annotation types restrict the use of the types they annotate.

The ElementType enumerated type is used in conjunction with the Target meta-annotation type to indicate where an annotation type may be used:

/**
 * A program element type.  The constants of this enumerated type
 * provide a simple classification of the declared elements in a
 * Java program.
 *
 * These constants are used in conjunction with the {@link Target}
 * meta-annotation type to specify where it is legal to use an
 * annotation type.
 */
public enum ElementType {
    /** Class, interface or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE
}

/**
 * Indicates the kinds of program element to which an annotation type
 * is applicable.  If a Target meta-annotation is not present on an
 * annotation type declaration, the declared type may be used on any
 * program element.  If such a meta-annotation is present, the compiler
 * will enforce the specified usage restriction.
 *
 * For example, this meta-annotation indicates that the declared type is
 * itself a meta-annotation type.  It can only be used on annotation type
 * declarations:
 *
 *    @Target(ANNOTATION_TYPE)
 *    public @interface MetaAnnotationType {
 *        ... 
 *    }
 *
 * This meta-annotation indicates that the declared type is intended solely
 * for use as a member type in complex annotation type declarations.  It
 * cannot be used to annotate anything directly:
 *
 *    @Target({}) 
 *    public @interface MemberType {
 *        ...
 *    }
 *
 * It is a compile-time error for a single ElementType constant to
 * appear more than once in a Target annotation.  For example, the
 * following meta-annotation is illegal:
 *
 *    // This annotation is illegal!
 *    @Target({FIELD, METHOD, FIELD})
 *    public  @interface Bogus {
 *        ...
 *    }
 */
@Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value;
}
Note that the Target annotation type's own declaration exemplifies its use, as well as the use of the Documented meta-annotation type, shown below.

The Documented meta-annotation type is used to indicate that annotations with a type should be documented:

/**
 * Indicates that annotations with a type are to be documented by javadoc
 * and similar tools by default.  This type should be used to annotate the 
 * declarations of types whose annotations affect the use of annotated
 * elements by their clients.  If a type declaration is annotated with
 * Documented, its annotations become part of the public API
 * of the annotated elements.
 */
@Documented @Target(ANNOTATION_TYPE)
public @interface Documented {
}
The RetentionPolicy enumerated type is used in conjunction with the Retention meta-annotation type to indicate how long an annotation is to be retained:

/**
 * Annotation retention policy.  The constants of this enumerated type
 * describe the various policies for retaining annotations.  They are used
 * in conjunction with the {@link Retention} meta-annotation type to specify
 * how long annotations are to be retained.
 */

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

/**
 * Indicates how long annotations with the annotated type are to
 * be retained.  If no Retention annotation is present on
 * an annotation type declaration, the retention policy defaults to
 * CLASS.
 *
 * A Target meta-annotation has effect only if the meta-annotated
 * type is use directly for annotation.  It has no effect if the meta-annotated
 * type is used as a member type in another annotation type.
 */
@Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}
The Inherited meta-attribute is used to indicate that annotations with a type are to be automatically inherited by subclasses or subclass methods:
/**
 * Indicates that an annotation type is automatically inherited.  If
 * an Inherited meta-annotation is present on an annotation type
 * declaration, and the user queries the annotation type on a class
 * declaration, and the class declaration has no annotation for this type,
 * then the class's superclass will automatically be queried for the
 * annotation type.  This process will be repeated until an annotation for this
 * type is found, or the top of the class hierarchy (Object)
 * is reached.  If no superclass has an annotation for this type, then
 * the query will indicate that the class in question has no such annotation.
 *
 * If an Inherited meta-annotation is present on an annotation type
 * declaration, and the user queries the annotation type on an instance method
 * declaration, and the declaration has no annotation for this type, then 
 * the query method will automatically search for a superclass method that is
 * overridden by the annotated method.  If such a method is found, it will be
 * queried for this annotation type.  This process will be repeated until an
 * annotation for this type is found or the top of the class hierarchy
 * (Object) is reached.  If the top of the class hierarchy is reached
 * without finding  an annotation for this type, then the query will indicate
 * that the method in question has no such annotation.
 *
 * Note that this meta-annotation type has no effect if the annotated
 * type is used to annotate anything other than a class or instance method
 * declaration.  Note also that this meta-annotation only causes annotations
 * to be inherited from superclasses; annotations on implemented interfaces
 * have no affect.
 */
@Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE)
public @interface Inherited {
}

V. Other Standard Annotation Types

Programmers occasionally overload a method declaration when they mean to override it. The classic example concerns the equals method. Programmers write the following:

    public boolean equals(Foo that) { ... }
when they mean to write:
    public boolean equals(Object that) { ... }
This is perfectly legal, but class Foo inherits the equals implementation from Object, which can cause some very subtle bugs. The following standard annotation type provides a way to avoid this trap:
package java.lang;
/**
 * Indicates that a method declaration is intended to override a concrete
 * method declaration in a superclass.  If a method is annotated with
 * this type but does not override a superclass method, compilers are
 * required to generate an error message.
 */
@Retention(SOURCE) @Target(METHOD)
public @interface Overrides { }
This annotation type allows the programmer to declare his belief that a method declaration overrides a superclass method:
    @Overrides public boolean equals(Foo that) { ... }
The compiler checks whether method actually overrides a superclass method, and reports an error if it does not, nipping the problem in the bud.

Note that this annotation type is not a fundamental part of this specification, but an initial use of the facility in the Java programming language.

VI. Reading Annotations

Annotation consumers may be divided into three groups:
  1. "Introspectors" - Programs that query runtime-visible annotations of their own program elements. These programs will load both annotated classes and annotation interfaces into the virtual machine. (By runtime-visible, we mean annotations whose retention policy is RUNTIME.)
  2. "Specific Tools" - Programs that query known annotation types of arbitrary external programs. Stub generators, for example, fall into this category. These programs will read annotated classes without loading them into the virtual machine, but will load annotation interfaces.
  3. "General Tools" - Programs that query arbitrary annotations of arbitrary external programs (such as compilers, documentation generators, and class browsers). These programs will load neither annotated classes nor annotation interfaces into the virtual machine. Such programs are said to operate "at arm's length."

Reading Annotations at Run Time

The Java core reflection API is extended to allow "introspectors" to query runtime-visible annotations of their own program elements. Types that represents a program element at runtime are extended to implement the java.lang.reflect.AnnotatedElement interface. The affected classes are java.lang.Class, which allows class annotations to be read; java.lang.reflect.AccessibleObject, which allows field, method, constructor, and enum constant annotations to be read; and java.lang.Package, which allows package annotations to be read.
/**
 * Represents an annotated element of the program currently running in this
 * JVM.  This interface allows annotations to be read reflectively.  All
 * annotations returned by methods in this interface are serializable.
 *
 * If an annotation object returned by a method in this interface
 * contains (directly or indirectly) one or more Class members
 * that refer to a class that is not accessible in this JVM, attempting
 * to read the class by calling the relevant Class-returning
 * method on the returned annotation (or an annotation referred to by
 * that annotation) will cause a {@link TypeNotPresentException}
 * to be thrown.
 */
public interface AnnotatedElement {
    /**
     * Returns true if an annotation for the specified type
     * is present on this element, else false.  This method
     * is designed primarily for convenient access to marker annotations.
     *
     * @param annotationType the Class object corresponding to the
     *        annotation type
     * @return true if an annotation for the specified annotation
     *     type is present on this element, else false
     * @throws NullPointerException if annotationType is null
     */
     boolean isAnnotationPresent(Class<? extends Annotation> annotationType);

    /**
     * Returns this element's annotation for the specified type if
     * such an annotation is present, else null.
     *
     * @param annotationType the Class object corresponding to the 
     *        annotation type
     * @return this element's annotation for the specified annotation type if
     *     present on this element, else null
     * @throws NullPointerException if annotationType is null
     */
    <T extends Annotation> T getAnnotation(Class<T> annotationType);

    /**
     * Returns all annotations present on this element.  (Returns an array
     * of length zero if this element has no annotations.)
     *
     * @return all annotations present on this element
     */
    Annotation[] getAnnotations();

    /**
     * Returns all annotations that are directly present on this
     * element.  Unlike the other methods in this interface, this method
     * ignores inherited annotations.  (Returns an array of length zero if
     * no annotations are directly present on this element.)
     *
     * @return All annotations directly present on this element
     */
    Annotation[] getDeclaredAnnotations();
}
To allow annotations on parameters to be read, a new method is added to java.lang.reflect.Method and java.lang.reflect.Constructor.
    /**
     * Returns an array of arrays that represent the annotations on the formal
     * parameters, in declaration order, of the method represented by
     * this Method object. (Returns an array of length zero if the
     * underlying method is parameterless.) The annotation objects contained
     * in the returned arrays are serializable.
     *
     * @returns an array of arrays that represent the annotations on the formal
     *    parameters, in declaration order, of the method represented by this
     *    Method object
     */
    public Annotation[][] getParameterAnnotations();
The following exception is added to java.lang:
/**
 * Thrown when an application tries to access a type using a string
 * representing the type's name, but no definition for the type with
 * the specified name can be found.   This exception differs from
 * {@link ClassNotFoundException} in that ClassNotFoundException
 * is a checked exception, whereas this exception is unchecked.
 *
 * Note that this exception may be used when undefined type variables
 * are accessed as well as when types (e.g., classes, interfaces or
 * annotation tyes) are loaded.
 */
public class TypeNotPresentException extends RuntimeException {
   /**
    * Constructs a TypeNotPresentException for the named type
    * with the specified cause.
    *
    * @param typeName the fully qualified name of the unavailable type
    * @param cause the exception that was thrown when the system attempted to
    *   load the named type, or null if unavailable or inapplicable
    */
   public TypeNotPresentException(String typeName, Throwable cause);

   /**
    * Returns the fully qualified name of the unavailable type.
    *
    * @return the fully qualified name of the unavailable type
    */
   public String typeName();
}
Here are examples of how these APIs can be used to read the annotations shown in Section III:
// Reading a normal annotation
Method m = TimeTravel.class.getMethod("travelThroughTime", new Class[] {Date.class});
RequestForEnhancement rfe = m.getAnnotation(RequestForEnhancement.class);
int id = rfe.id();
String synopsis = rfe.synopsis();
String engineer = rfe.engineer();
String date = rfe.date();

// Reading a marker annotation
boolean isPreliminary = TimeTravel.class.isAnnotationPresent(Preliminary.class);

// Reading a single-member annotation
String copyrightHolder = 
    OscillationOverthruster.class.getAnnotation(Copyright.class).value();

// Reading an array-valued single-member annotation
String[] endorsers = Lollipop.class.getAnnotation(Endorsers.class).value();

// Reading a single-member complex annotation
Name author = BitTwiddle.class.getAnnotation(Author.class).value();
String firstName = author.first();
String lastName = author.last();
The preceding APIs should also suffice for "specific tools" (which are willing to load annotation interfaces into the virtual machine but not annotated classes), assuming the existence of a tool that reads a class file without loading the class, and returns a "class mirror" object that implements AnnotatedElement. General tools, however, will need to read annotaions using an "at-arms-length" API, which allows annotations to be read without loading the annotated classes or annotation interfaces into the virtual machine.

One more method is added to the core reflection API. In order to distinguish an annotation type from a normal interface at run time, the following method is added to java.lang.Class:

/**
 * Returns true if this Class object represents an annotation type.
 * Note that if this method returns true, {@link #isInterface()} would also
 * return true, as all annotation types are also interfaces.
 *
 * @returns true if this class object represents an annotation type;
 *     false otherwise
 */
public boolean isAnnotationType();

VII. Library Support

This is the marker interface implemented by all annotation types. Note that it refines the contract on the Object methods equals and toString, ensuring that Annotation instances may be meaningfully printed and used as map keys or set elements:
package java.lang.annotation;

/**
 * Marker interface extended by every annotation interface.
 */
public interface Annotation {
    /**
     * Returns true if the specified object represents an annotation
     * that is logically equivalent to this one.  In other words,
     * returns true if the specified object is an instance of the same
     * annotation type as this instance, all of whose members are equal
     * to the corresponding member of this annotation, as defined below:
     * 
     *    Two corresponding primitive typed members whose values are
     *    x and y are considered equal if x == y,
     *    unless their type is float or double.
     *
     *    Two corresponding float members whose values
     *    are x and y are considered equal if
     *    Float.valueOf(x).equals(Float.valueOf(y)).
     *    (Unlike the == operator, NaN is considered equal
     *    to itself, and 0.0f unequal to -0.0f.) 
     *
     *    Two corresponding double members whose values
     *    are x and y are considered equal if
     *    Double.valueOf(x).equals(Double.valueOf(y)).
     *    (Unlike the == operator, NaN is considered equal
     *    to itself, and 0.0 unequal to -0.0.)
     *
     *    Two corresponding String, Class, enum, or
     *    annotation typed members whose values are x and y
     *    are considered equal if x.equals(y).  (Note that this
     *    definition is recursive for enum typed members.)
     *
     *    Two corresponding array typed members x and y
     *    are considered equal if Arrays.equals(x, y), for the
     *    appropriate overloading of {@link java.util.Arrays#equals}.
     * 
     *
     * @return true if the specified object represents an annotation
     *     that is logically equivalent to this one, otherwise false
     */
    boolean equals(Object obj);

    /**
     * Returns a string representation of this annotation.  The details
     * of the representation are implementation-dependent, but the following
     * may be regarded as typical:
     *
     *   @com.acme.util.Name(first=Alfred, middle=E., last=Neuman)
     *
     *
     * @return a string representation of this annotation
     */
    String toString();
}
In order to implement the equals, hashCode, and toString for annotations, we need content-based equals, hashCode, and toString methods for arrays. The utility class java.util.Arrays currently contains the equals methods, but not the others. Thus, we add the following methods to java.util.Arrays:
    // hashCode methods

    /**
     * Returns a hash code based on the contents of the specified array.
     * For any two long arrays a and b
     * such that Arrays.equals(a, b), it is also the case that
     * Arrays.hashCode(a) == Arrays.hashCode(b).
     *
     * The value returned by this method is the same value that would be
     * obtained by invoking the {@link List#hashCode() hashCode}
     * method on a {@link List} containing a sequence of {@link Long}
     * instances representing the elements of a in the same order.
     * If a is null, this method returns 0.
     *
     * @param the array whose hash value to compute
     * @return a content-based hash code for the array a
     */
    public static int hashCode(long a[]);
    
    // Analogous methods for each of the other seven primitive types (not shown)
    // plus these two for Object:
    
    /**
     * Returns a hash code based on the contents of the specified array.  If
     * the array contains other arrays as elements, the hash code is based on
     * their identities rather than their contents.  It is therefore
     * acceptable to invoke this method on an array that contains itself as an
     * element,  either directly or indirectly through one or more levels of
     * arrays.
     *
     * For any two arrays a and b such that
     * Arrays.equals(a, b), it is also the case that
     * Arrays.hashCode(a) == Arrays.hashCode(b).
     *
     * The value returned by this method is equal to the value that would
     * be returned by Arrays.asList(a).hashCode(), unless a
     * is null, in which case 0 is returned.
     *
     * @param the array whose content-based hash code to compute
     * @return a content-based hash code for the array a
     * @see #deepHashCode(Object[])
     */
    public static int hashCode(Object a[]);
    
    /**
     * Returns a hash code based on the "deep contents" of the specified
     * array.  If the array contains other arrays as elements, the
     * hash code is based on their contents and so on, ad infinitum.
     * It is therefore unacceptable to invoke this method on an array that
     * contains itself as an element, either directly or indirectly through
     * one or more levels of arrays.  The behavior of such an invocation is
     * undefined.
     *
     * For any two arrays a and b such that
     * Arrays.deepEquals(a, b), it is also the case that
     * Arrays.deepHashCode(a) == Arrays.deepHashCode(b).
     *
     * The computation of the value returned by this method is similar to
     * that of the value returned by {@link List#hashCode()} on a list
     * containing the same elements as a in the same order, with one
     * difference: If an element e of a is itself an array,
     * its hash code is computed not by calling e.hashCode(), but as
     * by calling the appropriate overloading of Arrays.hashCode(e)
     * if e is an array of a primitive type, or as by calling
     * Arrays.deepHashCode(e) recursively if e is an array
     * of a reference type.  If a is null, this method
     * returns 0.
     *
     * @param the array whose deep-content-based hash code to compute
     * @return a deep-content-based hash code for the array a
     * @see #hashCode(Object[])
     */
    public static int deepHashCode(Object a[]);
    
    
    // toString methods

    /**
     * Returns a string representation of the contents of the specified array.
     * The string representation consists of a list of the array's elements,
     * enclosed in square brackets ("[]").  Adjacent elements are
     * separated by the characters ", " (a comma followed by a
     * space).  Elements are converted to strings as by
     * String.valueOf(long).  Returns "null" if a
     * is null.
     *
     * @param the array whose string representation to return
     * @return a string representation of the array a
     */
    public static String toString(long[] a);
    
    // Analogous methods for each of the other seven primitive types (not shown)
    // plus these two for Object:
    
    /**
     * Returns a string representation of the contents of the specified array.
     * If the array contains other arrays as elements, they are converted to
     * strings by the {@link Object#toString} method inherited from
     * Object, which describes their identities rather than
     * their contents.  It is therefore acceptable to invoke this method on an
     * array that contains itself as an element, either directly or indirectly
     * through one or more levels of arrays.
     *
     * The value returned by this method is equal to the value that would
     * be returned by Arrays.asList(a).toString(), unless a
     * is null, in which case "null" is returned.
     *
     * @param the array whose string representation to return
     * @return a string representation of the array a
     * @see #deepToString()
     */
    public static String toString(Object[] a);
    
    /**
     * Returns a string representation of the "deep contents" of the specified
     * array.  If the array contains other arrays as elements, the string
     * representation contains their contents and so on, ad infinitum.  If
     * the specified array contains itself as an element, the element will be
     * converted to the string "(this array)".  If, however, the
     * specified array contains an indirect reference to itself through one or
     * more levels of arrays, the behavior of this method is undefined.
     *
     * The string representation consists of a list of the array's
     * elements, enclosed in square brackets ("[]").  Adjacent
     * elements are separated by the characters ", " (a comma
     * followed  by a space).  Elements are converted to strings as by
     * String.valueOf(Object), unless they are themselves
     * arrays.
     *
     * If an element e is an array of a primitive type, it is
     * converted to a string as by invoking the appropriate overloading of
     * Arrays.toString(e).  If an element e is an array of a
     * reference type, it is converted to a string as by invoking
     * Arrays.deepToString(e) recursively, unless e
     * is the specified array itself (in which case it is converted to
     * the string "(this array)").
     *
     * This method returns "null" if the specified array
     * is null.
     *
     * @param the array whose string representation to return
     * @return a string representation of the array a
     * @see #toString(Object[])
     */
    public static String deepToString(Object[] a);
    
    // This equals method goes with deepHashCode.  (The other eight equals methods
    // are already in java.util.Arrays.)
    
    /**
     * Returns true if the two specified arrays are deeply
     * equal to one another.  Unlike the @link{#equals{Object[],Object[])
     * method, this method is appropriate for use with nested arrays of
     * arbitrary depth.
     *
     * Two array references are considered deeply equal if both
     * are null, or if they refer to arrays that contain the same
     * number of elements and all corresponding pairs of elements in the two
     * arrays are deeply equal.
     *
     * Two possibly null elements e1 and e2 are
     * deeply equal if any of the following conditions hold:
     * 
     *    e1 and e2 are both arrays of object reference
     *    types, and Arrays.deepEquals(e1, e2) would return true
     *
     *    e1 and e2 are arrays of the same primitive
     *    type, and the appropriate overloading of
     *    Arrays.equals(e1, e2) would return true.
     *
     *    e1 == e2
     *
     *    e1.equals(e2) would return true.
     * 
     * Note that this definition permits null elements at any depth.
     *
     * If either of the specified arrays contain themselves as elements
     * either directly or indirectly through one or more levels of arrays,
     * the behavior of this method is undefined.
     *
     * @param a1 one array to be tested for equality
     * @param a2 the other array to be tested for equality
     * @return true if the two arrays are equal
     * @see #equals(Object[],Object[])
     */
    public static boolean deepEquals(Object[] a1, Object[] a2);

VIII. Annotation Type Evolution (Binary Compatibility)

This section discusses what happens when you modify an annotation type declaration. The short summary is that it's fine to add members with defaults; to add defaults for members that previously lacked them; or to add targets to annotation types. Other changes may cause trouble of varying degrees.

Adding an Annotation Type Member

Whenever a member is added to an annotation type for which compiled (or serialized) annotations exist, the new member should be given a default. If it is, all existing sources will continue to compile and all compiled annotations will continue to function properly. If a program attempts, using the revised annotation interface, to read the new member from an annotation that was compiled (or serialized) when the annotation type lacked this member, the default value will be returned. If no default exists, invoking the accessor for this member will throw a java.lang.IncompleteAnnotationError:
/**
 * Thrown to indicate that a program has attempted to access a member of
 * an annotation type that was added to the annotation type definition after
 * the annotation was compiled (or serialized).  This error will not be thrown
 * if the new member has a default value.
 */
public class IncompleteAnnotationError extends IncompatibleClassChangeError {
    /**
     * Constructs an IncompleteAnnotationError to indicate that
     * the named member was missing from the specified annotation type.
     *
     * @param annotationType the Class object for the annotation type
     * @param memberName the name of the missing member
     */
    public IncompleteAnnotationError(Class annotationType, String memberName) { }

    /**
     * Returns the Class object for the annotation type with the
     * missing member.
     *
     * @return the Class object for the annotation type with the
     *     missing member
     */
    public Class annotationType() { }

    /**
     * Returns the name of the missing member.
     *
     * @return the name of the missing member
     */
    public Class memberName() { }
}

Removing an Annotation Type Member

Removing a member from an annotation type will cause compilation errors for existing sources containing annotations with a value for the missing member. Class files that invoke the accessor for the removed member will fail at runtime with a java.lang.NoSuchMethodError. Removing a member from an annotation type will not, however, cause problems when reading annotations of the revised type that were compiled (or serialized) while the removed member was still present; the value for the deleted member will be silently discarded.

Changing the Type of an Annotation Type Member

A member's type must not be changed if compiled (or serialized) annotations exist. Attempting to read the annotation type using the revised interface will result in an AnnotationTypeMismatchError:
/**
 * Thrown to indicate that a program has attempted to access a member of
 * an annotation type whose type has changed after the annotation was compiled
 * (or serialized).
 */
public class AnnotationTypeMismatchError extends IncompatibleClassChangeError {
    /**
     * Constructs an AnnotationTypeMismatchError to indicate that
     * the type of the named member has changed.
     *
     * @param annotationType the Class object for the annotation type
     * @param memberName the name of the incorrectly typed member
     */
    public AnnotationTypeMismatchError(Class annotationType, String memberName) { }

    /**
     * Returns the Class object for the annotation type with the
     * incorrectly typed member.
     *
     * @return the Class object for the annotation type with the
     *    incorrectly typed member
     */
    public Class annotationType() { }

    /**
     * Returns the name of the incorrectly typed member.
     *
     * @return the name of the incorrectly typed member
     */
    public Class memberName() { }
}
Changing the type of an annotation type member may cause compilation errors for existing classes that contain annotations for the type, or that invoke the accessor for the member. Class files that invoke the accessor will fail at runtime with a java.lang.NoSuchMethodError.

Adding and Removing Defaults

It is always acceptable to add a default to a preexisting member. It is rarely acceptable to remove a default. Sources that depended on the default will no longer compile. Attempts to read the member from a compiled (or serialized) annotation that relied on the default will fail: the accessor will throw an IncompleteAnnotationError.

Adding and Removing Potential Targets

It is fine to add one or more potential targets to an existing annotation type using the Target meta-annotation type. If, however, one or more targets are removed, source files attempting to annotate removed targets will no longer compile. Class files containing annotations on the removed targets will behave as if those annotations were not present.

Changing Annotation Type Retention Policy

Adding a Retention meta-annotation when none was present has the following effect: If the value of the meta-annotation is SOURCE, class files containing annotations for the type will behave as if those annotations were not present. If the value of the meta-annotation is CLASS, the behavior will be unaffected. If the value of the meta-annotation is RUNTIME, annotations for the type will continue to behave as if the meta-annotation were not present. In other words, such annotations will not propagate from the class file to the virtual machine if the class file was generated before the Retention meta-annotation was added.

Changing the retention policy from SOURCE to CLASS or RUNTIME will behave as expected: existing class files will behave as if their sources contained no annotations for the type in question. The source must be recompiled to propagate the annotation into the class file. Changing the retention policy from RUNTIME to CLASS or SOURCE works fine. (If the new value of the meta-annotation is SOURCE, class files containing annotations for the type will behave as if those annotations were not present; if the new value is CLASS, the these annotations will not be readable at runtime.) Changing the retention policy from CLASS to SOURCE or RUNTIME behaves exactly as adding a SOURCE or RUNTIME meta-annotation when none was present.

IX. Class File Format for Annotations

This section describes five new predefined attributes that are used to represent annotations in the class file: RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations, and AnnotationDefault. The material contained in this section is destined for inclusion in Section 4.7 of the Java Virtual Machine Specification (JVMS).

The RuntimeVisibleAnnotations attribute

The RuntimeVisibleAnnotations attribute is a variable length attribute in the attributes table of the ClassFile, field_info, and method_info structures. The RuntimeVisibleAnnotations attribute records runtime-visible Java programming language annotations on the corresponding class, method, or field. Each ClassFile, field_info, and method_info structure may contain at most one RuntimeVisibleAnnotations attribute, which records all the runtime-visible Java programming language annotations on the corresponding program element. The JVM must make these annotations available so they can be returned by the appropriate reflective APIs.

The RuntimeVisibleAnnotations attribute has the following format:

    RuntimeVisibleAnnotations_attribute {
        u2 attribute_name_index;
        u4 attribute_length;
        u2 num_annotations;
        annotation annotations[num_annotations];
    }
The items of the RuntimeVisibleAnnotations structure are as follows:
attribute_name_index
The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "RuntimeVisibleAnnotations".
attribute_length
The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus dependent on the number of runtime-visible annotations represented by the structure, and their values.
num_annotations
The value of the num_annotations item gives the number of runtime-visible annotations represented by the structure. Note that a maximum of 65535 runtime-visible Java programming language annotations may be directly attached to a program element.
annotations
Each value of the annotations table represents a single runtime-visible annotation on a program element.

The annotation structure has the following format:

    annotation {
        u2    type_index;
        u2    num_member_value_pairs;
        {    u2    member_name_index;
             member_value value;
        }    member_value_pairs[num_member_value_pairs];
    }

The items of the annotation structure are as follows:

type_index
The value of the type_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing the annotation interface corresponding to the annotation represented by this annotation structure.
num_member_value_pairs
The value of the num_member_value_pairs item gives the number of member-value pairs in the annotation represented by this annotation structure. Note that a maximum of 65535 member-value pairs may be contained in a single annotation.
member_value_pairs
Each value of the member_value_pairs table represents a single member-value pair in the annotation represented by this annotation structure. Each member_value_pairs entry contains the following two items:
member_name_index
The value of the member_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the name of the annotation type member corresponding to this member_value_pairs entry.
value
The value item represents the value in the member-value pair represented by this member_value_pairs entry.

The member_value structure

The member_value structure is a discriminated union representing the value of a member-value pair. It is used to represent values in all class file attributes that describe annotations ( RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations, and RuntimeInvisibleParameterAnnotations).

The member_value structure has the following format:

    member_value {
        u1 tag;
        union {
            u2   const_value_index;
            {
                u2   type_name_index;
                u2   const_name_index;
            } enum_const_value;
            u2   class_info_index;
            annotation annotation_value; 
            {
                u2    num_values;
                member_value values[num_values];
            } array_value;
        } value;
    }

The items of the member_value structure are as follows:

tag
The tag item indicates the member type of this member-value pair. The letters 'B', 'C', 'D', 'F', 'I', 'J', 'S', and 'Z' indicate a primitive type. These letters are interpreted as BaseType characters (Table 4.2). The other legal values for tag are listed with their interpretations in this table:
tag valueMember Type
's' String
'e' enum constant
'c' class
'@' annotation type
'[' array
value
The value item represents the value of this annotation element. This item is a union. The tag item, above, determines which item of the union is to be used:
const_value_index
The const_value_index item is used if the tag item is one of 'B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', or 's'. The value of the const_value_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be of the correct entry type for the field type designated by the tag item, as specified in table 4.6, with one exception: if the tag is 's', the the value of the const_value_index item must be the index of a CONSTANT_Utf8 structure, rather than a CONSTANT_String.
enum_const_value
The enum_const_value item is used if the tag item is 'e'. The enum_const_value item consists of the following two items:
type_name_index
The value of the type_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the binary name (JLS 13.1) of the type of the enum constant represented by this member_value structure.
const_name_index
The value of the const_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the simple name of the enum constant represented by this member_value structure.
class_info_index
The class_info_index item is used if the tag item is 'c'. The class_info_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing the class represented by this member_value structure.
annotation_value
The annotation_value item is used if the tag item is '@'. The member_value structure represents a "nested" annotation.
array_value
The array_value item is used if the tag item is '['. The array_value item consists of the following two items:
num_values
The value of the num_values item gives the number of elements in the array-typed value represented by this member_value structure. Note that a maximum of 65535 elements are permitted in an array-typed member value.
values
Each element of the values table gives the value of an element of the array-typed value represented by this member_value structure.

The RuntimeInvisibleAnnotations attribute

The RuntimeInvisibleAnnotations attribute is similar to the RuntimeVisibleAnnotations attribute, except that the annotations represented by a RuntimeInvisibleAnnotations attribute must not be made available for return by reflective APIs, unless the JVM has been instructed to retain these annotations via some implementation-specific mechanism such as a command line flag. In the absence of such instructions, the JVM ignores this attribute.

The RuntimeInvisibleAnnotations attribute is a variable length attribute in the attributes table of the ClassFile, field_info, and method_info structures. The RuntimeInvisibleAnnotations attribute records runtime-invisible Java programming language annotations on the corresponding class, method, or field. Each ClassFile, field_info, and method_info structure may contain at most one RuntimeInvisibleAnnotations attribute, which records all the runtime-invisible Java programming language annotations on the corresponding program element.

The RuntimeInvisibleAnnotations attribute has the following format:

    RuntimeInvisibleAnnotations_attribute {
        u2 attribute_name_index;
        u4 attribute_length;
        u2 num_annotations;
        annotation annotations[num_annotations];
    }
The items of the RuntimeInvisibleAnnotations structure are as follows:
attribute_name_index
The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "RuntimeInvisibleAnnotations".
attribute_length
The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus dependent on the number of runtime-invisible annotations represented by the structure, and their values.
num_annotations
The value of the num_annotations item gives the number of runtime-invisible annotations represented by the structure. Note that a maximum of 65535 runtime-invisible Java programming language annotations may be directly attached to a program element.
annotations
Each value of the annotations table represents a single runtime-invisible annotation on a program element.

The RuntimeVisibleParameterAnnotations attribute

The RuntimeVisibleParameterAnnotations attribute is a variable length attribute in the attributes table of the method_info structure. The RuntimeVisibleParameterAnnotations attribute records runtime-visible Java programming language annotations on the parameters of the corresponding method. Each method_info structure may contain at most one RuntimeVisibleParameterAnnotations attribute, which records all the runtime-visible Java programming language annotations on the parameters of the corresponding method. The JVM must make these annotations available so they can be returned by the appropriate reflective APIs.

The RuntimeVisibleParameterAnnotations attribute has the following format:

    RuntimeVisibleParameterAnnotations_attribute {
        u2 attribute_name_index;
        u4 attribute_length;
        u1 num_parameters;
        {
            u2 num_annotations;
            annotation annotations[num_annotations];
        } parameter_annotations[num_parameters];
    }
The items of the RuntimeVisibleParameterAnnotations structure are as follows:
attribute_name_index
The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "RuntimeVisibleParameterAnnotations".
attribute_length
The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus dependent on the number of parameters, the number of runtime-visible annotations on each parameter, and their values.
num_parameters
The value of the num_parameters item gives the number of parameters of the method represented by the method_info structure on which the annotation occurs. (This duplicates information that could be extracted from the method descriptor.)
parameter_annotations
Each value of the parameter_annotations table represents all of the runtime-visible annotations on a single parameter. The sequence of values in the table corresponds to the sequence of parameters in the method signature. Each parameter_annotations entry contains the following two items:
num_annotations
The value of the num_annotations item indicates the number of runtime-visible annotations on the parameter corresponding to the sequence number of this parameter_annotations element.
annotations
Each value of the annotations table represents a single runtime-visible annotation on the parameter corresponding to the sequence number of this parameter_annotations element.

The RuntimeInvisibleParameterAnnotations attribute

The RuntimeInvisibleParameterAnnotations attribute is similar to the RuntimeVisibleParameterAnnotations attribute, except that the annotations represented by a RuntimeInvisibleParameterAnnotations attribute must not be made available for return by reflective APIs, unless the JVM has specifically been instructed to retain these annotations via some implementation-specific mechanism such as a command line flag. In the absence of such instructions, the JVM ignores this attribute.

The RuntimeInvisibleParameterAnnotations attribute is a variable length attribute in the attributes table of the method_info structure. The RuntimeInvisibleParameterAnnotations attribute records runtime-invisible Java programming language annotations on the parameters of the corresponding method. Each method_info structure may contain at most one RuntimeInvisibleParameterAnnotations attribute, which records all the runtime-invisible Java programming language annotations on the parameters of the corresponding method.

The RuntimeInvisibleParameterAnnotations attribute has the following format:

    RuntimeInvisibleParameterAnnotations_attribute {
        u2 attribute_name_index;
        u4 attribute_length;
        u1 num_parameters;
        {
            u2 num_annotations;
            annotation annotations[num_annotations];
        } parameter_annotations[num_parameters];
    }
The items of the RuntimeInvisibleParameterAnnotations structure are as follows:
attribute_name_index
The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "RuntimeInvisibleParameterAnnotations".
attribute_length
The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus dependent on the number of parameters, the number of runtime-invisible annotations on each parameter, and their values.
num_parameters
The value of the num_parameters item gives the number of parameters of the method represented by the method_info structure on which the annotation occurs. (This duplicates information that could be extracted from the method descriptor.)
parameter_annotations
Each value of the parameter_annotations table represents all of the runtime-invisible annotations on a single parameter. The sequence of values in the table corresponds to the sequence of parameters in the method signature. Each parameter_annotations entry contains the following two items:
num_annotations
The value of the num_annotations item indicates the number of runtime-invisible annotations on the parameter corresponding to the sequence number of this parameter_annotations element.
annotations
Each value of the annotations table represents a single runtime-invisible annotation on the parameter corresponding to the sequence number of this parameter_annotations element.

The AnnotationDefault attribute

The AnnotationDefault attribute is a variable length attribute in the attributes table of certain method_info structures, namely those representing members of annotation types. The AnnotationDefault attribute records the default value for the member represented by the method_info structure. Each method_info structures representing a member of an annotation types may contain at most one AnnotationDefault attribute. The JVM must make this default value available so it can be applied by appropriate reflective APIs.

The AnnotationDefault attribute has the following format:

    AnnotationDefault_attribute {
        u2 attribute_name_index;
        u4 attribute_length;
        member_value default_value;
    }
The items of the AnnotationDefault structure are as follows:
attribute_name_index
The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure representing the string "AnnotationDefault".
attribute_length
The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes. The value of the attribute_length item is thus dependent on the default value.
default_value
The default_value item represents the default value of the annotation type member whose default value is represented by this AnnotationDefault attribute.

Package-level Annotations

The following information presumably belongs in Chapter 7 of the JVMS, "Compiling for the Java Virtual Machine."

Package-level annotations are a special case. When the compiler encounters an annotated package declaration, it must emit a synthetic interface named package-name.package-info with no superinterfaces or members (exculding those methods implicitly declared as per JLS 9.2). The synthetic interface has the default access level ("package-private"). The package-level annotations are stored in the RuntimeVisibleAnnotations and RuntimeInvisibleAnnotations attributes of the ClassFile structure.

Appendix I. Reading Annotations "at Arm's Length"

The Doclet API is not currently part of any standard. This (non-normative) appendix shows how the Doclet API will be modified to support program annotations. Note that this API is rather low-level: it ignores member defaults and annotation inheritance. This is consistent with rest of the Doclet API.

The following interfaces are added to com.sun.javadoc:

/**
 * Represents an annotation.
 * An annotation associates a value with each member of an annotation type.
 */
public interface AnnotationDesc {
    /**
     * Returns the annotation type of this annotation.
     *
     * @return the annotation type of this annotation
     */
    AnnotationTypeDoc annotationType();

    /**
     * Returns this annotation's members and their values.
     * Only those explicitly present in the annotation are
     * included, not those assuming their default values.
     * Returns an empty array if there are none.
     *
     * @return this annotation's members and their values
     */
    MemberValuePair[] memberValues();


    /**
     * Represents an association between an annotation type member
     * and one of its values.
     */
    public interface MemberValuePair {

	/**
	 * Returns the annotation type member.
	 *
	 * @return the annotation type member
	 */
	AnnotationTypeMemberDoc member();

	/**
	 * Returns the value associated with the annotation type member.
	 *
	 * @return the value associated with the annotation type member
	 */
	AnnotationValue value();
    }
}


/**
 * Represents an annotation type.
 */
public interface AnnotationTypeDoc extends ClassDoc {

    /**
     * Returns the members of this annotation type.
     * Returns an empty array if there are none.
     *
     * @return the members of this annotation type
     */
    AnnotationTypeMemberDoc[] members();
}


/**
 * Represents a member of an annotation type.
 */
public interface AnnotationTypeMemberDoc extends MethodDoc {

    /**
     * Returns the default value of this member.
     * Returns null if this member has no default.
     *
     * @return the default value of this member
     */
    AnnotationValue defaultValue();
}

/**
 * Represents a value of an annotation type member.
 */
public interface AnnotationValue {

    /**
     * Returns the value.
     * The type of the returned object is one of the following:
     *
     *    - a wrapper class for a primitive type
     *    - String
     *    - ClassDoc
     *    - FieldDoc (representing an enum constant)
     *    - AnnotationDesc
     *    - AnnotationValue[]
     *
     * @return the value
     */
    Object value();

    /**
     * Returns a string representation of the value.
     *
     * @return the text of a Java language annotation value expression
     *		whose value is the value of this annotation type member
     */
    String toString();
}
Several existing doclet interfaces are modified as follows:
========================================
Doc
========================================
Add methods:

    /**
     * Is this Doc item an annotation type?
     *
     * @return true if it represents an annotation type
     */
    boolean isAnnotationType();

    /**
     * Is this Doc item an annotation type member?
     *
     * @return true if it represents an annotation type member
     */
    boolean isAnnotationTypeMember();


========================================
PackageDoc
========================================
Add methods:

    /**
     * Get included annotation types in this package.
     *
     * @return included annotation types in this package
     */
    AnnotationTypeDoc[] annotationTypes();

    /**
     * Get the annotations of this package.
     * Return an empty array if there are none.
     *
     * @return the annotations of this package
     */
    AnnotationDesc[] annotations();

Clarify that interfaces() excludes annotation types.


========================================
ClassDoc
========================================
Clarify that methods() and methods(boolean) exclude annotation type members.


========================================
Parameter
========================================
Add method:

    /**
     * Get the annotations of this parameter.
     * Return an empty array if there are none.
     *
     * @return the annotations of this parameter
     */
    AnnotationDesc[] annotations();


========================================
ProgramElementDoc
========================================
Add method:

    /**
     * Get the annotations of this program element.
     * Return an empty array if there are none.
     *
     * @return the annotations of this program element
     */
    AnnotationDesc[] annotations();

Clarify that the string returned by modifiers() does not include annotations.


========================================
Type
========================================
Add method:

    /**
     * Return this type as an AnnotationTypeDoc if it represents
     * an annotation type.
     *
     * @return an AnnotationTypeDoc if the type is an annotation
     *         type, or null if it is not
     */
    AnnotationTypeDoc asAnnotationTypeDoc();

Appendix II. Design FAQ

This collection of frequently asked questions concerning the design of the program annotation facility is meant to serve as a design rationale.

Annotation Types

  1. Why didn't you use a new attribute keyword to declare annotation types?
  2. Given the huge number of Java programs already in existence, there is a great advantage to providing source compatibility. Many programs use attribute as an identifier, and those programs would no longer be legal. If fact, it would not have been possible to do this, as it conflicts with javax.print.attribute.

  3. Why did you use the at-sign (@) to indicate an annotation rather than brackets([])?
  4. Two reasons: (1) It is reminiscent of Javadoc tags, a preexisting ad hoc annotation facility in the Java programming language, and (2) It is mnemonic: at = a[nnotation] t[ype].

  5. Why do you use method declaration syntax (String name();) to declare attribute members instead of field syntax (String name;)?

    Because annotation type declarations really do declare an interface (which is used to access the annotations). Thus, it makes sense that annotation types and ordinary interfaces share a common declaration syntax. Further, the field-like notation would be confusing because the semantics are different from fields. In particular, the default semantics are different from field initialization semantics.

  6. Why don't you support attribute subtyping (where one attribute type extends another)?
  7. It complicates the attribute type system, and makes it much more difficult to write "Specific Tools" (per the taxonomy in Section VI).

  8. Why is it illegal for an annotation type to contain a member of the same type?
  9. At first glance it would appear that you could never annotate with such a type, so the prohibition might seem unnecessary, but you can get yourself into trouble if you also provide a default:

    @interface Foo {
        Foo foo() default @Foo;
    }
    
    @Foo int i;
    
    This is legal, but the resulting annotation is self-referential (or infinite), as well as totally useless.

Annotations

  1. Why is it illlegal to use null as an annotation value?
  2. It is consistent with the fact that null is not a compile-time constant expression (JLS 15.28). Also it's consistent with the proposal that null is not a legal case label in a switch statement on an enum expression. It eliminates a behavioral difference between primitive annotation members and reference type annotation members, and reduces the likelihood of a NullPointerException at run time.

  3. Why is it illegal annotate a single element repeatedly with the same annotation type?
  4. A similar effect is available by annotating once with an annotation type whose sole member is of an array type. The resulting system is simpler and cleaner: you don't have to worry about whether you're going to get back a single instance of the annotation type or multiple instances when you query an annotation. Also it's consistent with the usual restriction on modifiers.

  5. Why can't you annotate arbitrary program elements such as blocks and individual statements?

    This would greatly complicate the annotation syntax: We would have to sacrifice the simplicity of saying that annotations are simply modifiers, which can be used on declarations.

  6. Why is a MemberValue of a non-array and non-annotation type restricted to a ConditionalExpression, rather than an Expression?
  7. To eliminate a syntactic ambiguity involving assignment operators.

Semantics

  1. Why don't you put local variable annotations into the class file?
  2. There's no place to put them. The class file format does not describe or expose structure within a method. If, in future, the class file format is redesigned to provide such structural information, this decision will be reconsidered.

  3. Why doesn't the Overrides annotation let you confirm that you've overridden a method in an interface (as well as a superclass)?

    The compiler already tells you if you've failed to override an interface method (assuming you implement the interface). It would be redundant and confusing to offer similar functionality with the Overrides annotation.

Appendix III. Usage Notes

Programmers using annotations should be aware that programs acquire dependencies on any annotation types they use, just as they acquire dependencies on libraries. In order to ensure portability, programmers may elect to avoid using proprietary annotation types.

Appendix IV. Implementation Notes

The classes used to represent annotations are created at run time using dynamic proxies (see java.lang.reflect.Proxy).

Appendix V. Issues

Some people have expressed concern over the fact that annotating a program ties you to the annotation type, to the extent that you can't even compile the annotated program if the class file for the annotation type is unavailable. Annotations are no different in this respect from method invocations or field accesses: if you use a library, the library must be present in order to compile your program.

For many annotations, this behavior is exactly what you want, as the annotation results in the production of some artifact that is required to run the program (such as an additional source file, or an XML document). Some annotations, however, are merely "structured comments," which are not intended to have any affect on the running program. For example, a UML modeling tool might annotate program elements with model information for its own use. If the compiler knew that a given annotation were of this character, it could safely ignore the annotation even if the class file for its annotation type were unavailable. This would allow people to compile the program even if they did not have access to the class file for the annotation type.

Unfortunately there is no way to indicate that a given annotation type is of this character. It cannot be done with a meta-annotation, as the compiler cannot read the meta-annotation if it does not have access to the annotation type.

There are other alternatives. For example, we could provide a second annotation syntax (say, @@(a=1, b=3)) that indicates to the compiler that an annotation can be ignored if its class file is not present. However, this places the decision as to whether an annotation should be ignored in the hands of the annotater, rather than the annotation type author. It should be up to the author of an annotation type to decide whether annotations of that type can be safely ignored.

A similar idea is to provide a compiler flag that instructs the compiler to ignore certain annotations. Again, this idea is questionable, as it places the decision in the wrong hands. This alternative, as well as the previous one, could result in programs that simply did not run if the programmer told the compiler to ignore critical metadata.

Do you consider it problematic that annotations tie you to annotation types in the same way that method invocations tie you libraries? If so, can you think of an acceptable solution to the problem?

Appendix VI. Change Log

Changes in Public Draft

  1. Added this Appendix.
  2. Minor style change in annotation examples (Section III): added a newline between the annotation and the the declaration it annotates for all but marker annotation.
  3. Added examples of illegal circular annotation type declarations to clarify what is prohibited.
  4. Added examples of permitted circular meta-annotations to clarify that circularities of any length are permitted.
  5. Added a small amount of introductory text for each standard meta-annotation type.
  6. Defined the term runtime-visible on first use.
  7. Added examples to Section VI ("Reading Annotations at Run Time"). This completes the picture: now we have corresponding examples of annotation type declaration, annotation, and reading annotations.
  8. Clarified the taxonomy of "annotation consumers" that begins Section VI to indicate that "load" means "to load a class into the virtual machine," and to define the term "at arm's length."
  9. Clarified that annotation inheritance applies only to superclasses, not to implemented interfaces.
  10. Changed the name of ClassNotPresentException to TypeNotPresentException to make more broadly applicable.
  11. Changed the name of the file in which package-level annotations are to be placed from Package.java to package-info.java.
  12. Eliminated the enum constant ENUM_CONSTANT from the enum type ElementType (which is used in conjunction with the Target meta-annotation). An enum constant is an implicit field declaration, and the FIELD constant is now specified to include enum constants.
  13. Clarified that the compiler must enforce annotation usage restrictions specified with the Target meta-attribute.
  14. Added @Retention(RUNTIME) meta-annotation to annotation type declarations for Target and Retention.
  15. Added Section VII ("Library Support"). It contains the marker interface java.lang.Annotation (which now refines the contracts of equals and toString to do the right thing), as well as utility methods for manipulating arrays.
  16. Added explanatory text to Section IV ("Other Standard Annotation Types") motivating the need for the Overrides annotation type.
  17. Added @Retention(SOURCE) meta-annotation on Overrides annotation type declaration.
  18. Moved the Class File Format to the end (Section IX) for readability.
  19. Modified "Changing Annotation Type Retention Policy" in Section VII ("Annotation Type Evolution") to indicate that adding a retention policy of RUNTIME would not cause CLASS annotations in existing class files to be readable at run time.
  20. Modified Appendix I (Reading Annotations "at Arm's Length") to reflect the changes to the Doclet API that were actually implemented: filled in a few holes in the original sketch, and brought a few names into line with Doclet API conventions.
  21. Removed both issues from Appendix V, as there was near-unanimity on both open issues among reviewers of the Community Draft.
  22. Added issue concerning "ignorable annotations."
  23. Added several entries to the FAQ.
  24. Modified the class file format of package-level metadata to indicate that the synthetically generated type is an interface rather than a class, and to fill in some details.
  25. Minor fixups to travelThroughTime example annotation and Inherits FAQ as per Eamonn's letter.
  26. Added minor clarifications as per Doug's letter.
  27. Eliminated restriction on fields and nested class, interface, enum, or annotation type declarations within annotation type declarations.
  28. Reordered list of parts at the end of section I
  29. Moved section VIII after section IV.
  30. Corrected lots of typos that Simon found
  31. Removed sentence from Appendix I that said isInterface() returns false for annotation types.
  32. Added boldface warning on illegal Target annotation example as per Cedric's request.
  33. Clarified the manner in which the AnnotatedElement API could be used by "specific tools."

Copyright 2002-2003 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, California 94303 U.S.A. All rights reserved.