Java annotation

Last updated

In the Java computer programming language, an annotation is a form of syntactic metadata that can be added to Java source code. [1] Classes, methods, variables, parameters and Java packages may be annotated. Like Javadoc tags, Java annotations can be read from source files. Unlike Javadoc tags, Java annotations can also be embedded in and read from Java class files generated by the Java compiler. This allows annotations to be retained by the Java virtual machine at run-time and read via reflection. [2] It is possible to create meta-annotations out of the existing ones in Java. [3]

Contents

History

The Java platform has various ad-hoc annotation mechanisms—for example, the transient modifier, or the @Deprecated javadoc tag. The Java Specification Request JSR-175 introduced the general-purpose annotation (also known as metadata) facility to the Java Community Process in 2002; it gained approval in September 2004. [4] Annotations became available in the language itself beginning with version 1.5 of the Java Development Kit (JDK). The apt tool provided a provisional interface for compile-time annotation processing in JDK version 1.5; JSR-269 formalized this, and it became integrated into the javac compiler in version 1.6.

Built-in annotations

Java defines a set of annotations that are built into the language. Of the seven standard annotations, three are part of java.lang, and the remaining four are imported from java.lang.annotation. [5] [6]

Annotations applied to Java code:

Annotations applied to other annotations (also known as "Meta Annotations"):

Since Java 7, three additional annotations have been added to the language.

Example

Built-in annotations

This example demonstrates the use of the @Override annotation. It instructs the compiler to check parent classes for matching methods. In this case, an error is generated because the gettype() method of class Cat doesn't in fact override getType() of class Animal like is desired, because of the mismatching case. If the @Override annotation were absent, a new method of name gettype() would be created in class Cat.

publicclassAnimal{publicvoidspeak(){}publicStringgetType(){return"Generic animal";}}publicclassCatextendsAnimal{@Overridepublicvoidspeak(){// This is a good override.System.out.println("Meow.");}@OverridepublicStringgettype(){// Compile-time error due to typo: should be getType() not gettype().return"Cat";}}

Custom annotations

Annotation type declarations are similar to normal interface declarations. An at-sign (@) precedes the keyword "interface".

// @Twizzle is an annotation to method toggle().@Twizzlepublicvoidtoggle(){}// Declares the annotation Twizzle.public@interfaceTwizzle{}

Annotations may include a set of key-value pairs, which are modeled as methods of the annotation type. Each method declaration defines an element of the annotation type. Method declarations must not have any parameters or a throws clause. Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types. Methods can have default values.

// Same as: @Edible(value = true)@Edible(true)Itemitem=newCarrot();public@interfaceEdible{booleanvalue()defaultfalse;}@Author(first="Oompah",last="Loompah")Bookbook=newBook();public@interfaceAuthor{Stringfirst();Stringlast();}

Annotations themselves may be annotated to indicate where and when they can be used:

@Retention(RetentionPolicy.RUNTIME)// Make this annotation accessible at runtime via reflection.@Target({ElementType.METHOD})// This annotation can only be applied to class methods.public@interfaceTweezable{}

The compiler reserves a set of special annotations (including @Deprecated, @Override and @SuppressWarnings) for syntactic purposes.

Annotations are often used by frameworks as a way of conveniently applying behaviours to user-defined classes and methods that must otherwise be declared in an external source (such as an XML configuration file) or programmatically (with API calls). The following, for example, is an annotated JPA data class:

@Entity// Declares this an entity bean@Table(name="people")// Maps the bean to SQL table "people"publicclassPersonimplementsSerializable{@Id// Map this to the primary key column.@GeneratedValue(strategy=GenerationType.AUTO)// Database will generate new primary keys, not us.privateIntegerid;@Column(length=32)// Truncate column values to 32 characters.privateStringname;publicIntegergetId(){returnid;}publicvoidsetId(Integerid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}}

The annotations are not method calls and will not, by themselves, do anything. Rather, the class object is passed to the JPA implementation at run-time, which then extracts the annotations to generate an object–relational mapping.

A complete example is given below:

packagecom.annotation;importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Inherited;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Documented@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE,ElementType.METHOD,ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,ElementType.PACKAGE,ElementType.FIELD,ElementType.LOCAL_VARIABLE})@Inheritedpublic@interfaceUnfinished{publicenumPriority{LOW,MEDIUM,HIGH}Stringvalue();String[]changedBy()default"";String[]lastChangedBy()default"";Prioritypriority()defaultPriority.MEDIUM;StringcreatedBy()default"James Gosling";StringlastChanged()default"2011-07-08";}
packagecom.annotation;public@interfaceUnderConstruction{Stringowner()default"Patrick Naughton";Stringvalue()default"Object is Under Construction.";StringcreatedBy()default"Mike Sheridan";StringlastChanged()default"2011-07-08";}
packagecom.validators;importjavax.faces.application.FacesMessage;importjavax.faces.component.UIComponent;importjavax.faces.context.FacesContext;importjavax.faces.validator.Validator;importjavax.faces.validator.ValidatorException;importcom.annotation.UnderConstruction;importcom.annotation.Unfinished;importcom.annotation.Unfinished.Priority;importcom.util.Util;@UnderConstruction(owner="Jon Doe")publicclassDateValidatorimplementsValidator{publicvoidvalidate(FacesContextcontext,UIComponentcomponent,Objectvalue)throwsValidatorException{Stringdate=(String)value;StringerrorLabel="Please enter a valid date.";if(!component.getAttributes().isEmpty()){errorLabel=(String)component.getAttributes().get("errordisplayval");}if(!Util.validateAGivenDate(date)){@Unfinished(changedBy="Steve",value="whether to add message to context or not, confirm",priority=Priority.HIGH)FacesMessagemessage=newFacesMessage();message.setSeverity(FacesMessage.SEVERITY_ERROR);message.setSummary(errorLabel);message.setDetail(errorLabel);thrownewValidatorException(message);}}}

Processing

When Java source code is compiled, annotations can be processed by compiler plug-ins called annotation processors. Processors can produce informational messages or create additional Java source files or resources, which in turn may be compiled and processed. However, annotation processors cannot modify the annotated code itself. (Code modifications may be implemented using methods beyond the Java Language Specification.) The Java compiler conditionally stores annotation metadata in the class files, if the annotation has a RetentionPolicy of CLASS or RUNTIME. Later, the JVM or other programs can look for the metadata to determine how to interact with the program elements or change their behavior.

In addition to processing an annotation using an annotation processor, a Java programmer can write their own code that uses reflection to process the annotation. Java SE 5 supports a new interface that is defined in the java.lang.reflect package. This package contains the interface called AnnotatedElement that is implemented by the Java reflection classes including Class, Constructor, Field, Method, and Package. The implementations of this interface are used to represent an annotated element of the program currently running in the Java Virtual Machine. This interface allows annotations to be read reflectively.

The AnnotatedElement interface provides access to annotations having RUNTIME retention. This access is provided by the getAnnotation, getAnnotations, and isAnnotationPresent methods. Because annotation types are compiled and stored in byte code files just like classes, the annotations returned by these methods can be queried just like any regular Java object. A complete example of processing an annotation is provided below:

importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;// This is the annotation to be processed// Default for Target is all Java Elements// Change retention policy to RUNTIME (default is CLASS)@Retention(RetentionPolicy.RUNTIME)public@interfaceTypeHeader{// Default value specified for developer attributeStringdeveloper()default"Unknown";StringlastModified();String[]teamMembers();intmeaningOfLife();}
// This is the annotation being applied to a class@TypeHeader(developer="Bob Bee",lastModified="2013-02-12",teamMembers={"Ann","Dan","Fran"},meaningOfLife=42)publicclassSetCustomAnnotation{// Class contents go here}
// This is the example code that processes the annotationimportjava.lang.annotation.Annotation;importjava.lang.reflect.AnnotatedElement;publicclassUseCustomAnnotation{publicstaticvoidmain(String[]args){Class<SetCustomAnnotation>classObject=SetCustomAnnotation.class;readAnnotation(classObject);}staticvoidreadAnnotation(AnnotatedElementelement){try{System.out.println("Annotation element values: \n");if(element.isAnnotationPresent(TypeHeader.class)){// getAnnotation returns Annotation typeAnnotationsingleAnnotation=element.getAnnotation(TypeHeader.class);TypeHeaderheader=(TypeHeader)singleAnnotation;System.out.println("Developer: "+header.developer());System.out.println("Last Modified: "+header.lastModified());// teamMembers returned as String []System.out.print("Team members: ");for(Stringmember:header.teamMembers())System.out.print(member+", ");System.out.print("\n");System.out.println("Meaning of Life: "+header.meaningOfLife());}}catch(Exceptionexception){exception.printStackTrace();}}}

See also

Related Research Articles

A visitor pattern is a software design pattern and separates the algorithm from the object structure. Because of this separation new operations can be added to existing object structures without modifying the structures. It is one way to follow the open/closed principle in object-oriented programming and software engineering.

Java Platform, Standard Edition is a computing platform for development and deployment of portable code for desktop and server environments. Java SE was formerly known as Java 2 Platform, Standard Edition (J2SE).

In computing, the Java Remote Method Invocation is a Java API that performs remote method invocation, the object-oriented equivalent of remote procedure calls (RPC), with support for direct transfer of serialized Java classes and distributed garbage-collection.

In computing, the Java API for XML Processing, or JAXP, one of the Java XML Application programming interfaces, provides the capability of validating and parsing XML documents. It has three basic parsing interfaces:

In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.

In software design and engineering, the observer pattern is a software design pattern in which an object, named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

<span class="mw-page-title-main">Swing (Java)</span> Java-based GUI toolkit

Swing is a GUI widget toolkit for Java. It is part of Oracle's Java Foundation Classes (JFC) – an API for providing a graphical user interface (GUI) for Java programs.

This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries. For a more detailed comparison of the platforms, see Comparison of the Java and .NET platforms.

<span class="mw-page-title-main">Method overriding</span> Language feature in object-oriented programming

Method overriding, in object-oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes. In addition to providing data-driven algorithm-determined parameters across virtual network interfaces, it also allows for a specific type of polymorphism (subtyping). The implementation in the subclass overrides (replaces) the implementation in the superclass by providing a method that has same name, same parameters or signature, and same return type as the method in the parent class. The version of a method that is executed will be determined by the object that is used to invoke it. If an object of a parent class is used to invoke the method, then the version in the parent class will be executed, but if an object of the subclass is used to invoke the method, then the version in the child class will be executed. This helps in preventing problems associated with differential relay analytics which would otherwise rely on a framework in which method overriding might be obviated. Some languages allow a programmer to prevent a method from being overridden.

<span class="mw-page-title-main">Java syntax</span> Set of rules defining correctly structured program

The syntax of Java is the set of rules defining how a Java program is written and interpreted.

In computer programming, an entry point is the place in a program where the execution of a program begins, and where the program has access to command line arguments.

In the Java programming language, the final keyword is used in several contexts to define an entity that can only be assigned once.

<span class="mw-page-title-main">Scala (programming language)</span> General-purpose programming language

Scala is a strong statically typed high-level general-purpose programming language that supports both object-oriented programming and functional programming. Designed to be concise, many of Scala's design decisions are aimed to address criticisms of Java.

XMLBeans is a Java-to-XML binding framework which is part of the Apache Software Foundation XML project.

<span class="mw-page-title-main">Attribute (computing)</span> Metadata which defines a property

In computing, an attribute is a specification that defines a property of an object, element, or file. It may also refer to or set the specific value for a given instance of such. For clarity, attributes should more correctly be considered metadata. An attribute is frequently and generally a property of a property. However, in actual usage, the term attribute can and is often treated as equivalent to a property depending on the technology being discussed. An attribute of an object usually consists of a name and a value. For an element these can be a type and class name, while for a file these can be a name and an extension, respectively.

Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a type or method to operate on objects of various types while providing compile-time type safety". The aspect compile-time type safety was not fully achieved, since it was shown in 2016 that it is not guaranteed in all cases.

In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral (null) behavior. The null object design pattern, which describes the uses of such objects and their behavior, was first published as "Void Value" and later in the Pattern Languages of Program Design book series as "Null Object".

Static import is a feature introduced in the Java programming language that allows members which have been scoped within their container class as public static, to be used in Java code without specifying the class in which the field has been defined. This feature was introduced into the language in version 5.0.

Java Database Connectivity (JDBC) is an application programming interface (API) for the Java programming language which defines how a client may access a database. It is a Java-based data access technology used for Java database connectivity. It is part of the Java Standard Edition platform, from Oracle Corporation. It provides methods to query and update data in a database, and is oriented toward relational databases. A JDBC-to-ODBC bridge enables connections to any ODBC-accessible data source in the Java virtual machine (JVM) host environment.

Castor is a data binding framework for Java with some features like Java to Java-to-XML binding, Java-to-SQL persistence, paths between Java objects, XML documents, relational tables, etc. Castor is one of the oldest data binding projects.

References

  1. "Annotations". Sun Microsystems. Archived from the original on 2011-09-25. Retrieved 2011-09-30..
  2. Sun Microsystems (2005). Java(TM) Language Specification (3rd ed.). Prentice Hall. ISBN   0-321-24678-0..
  3. Dare Obasanjo (2007). "A COMPARISON OF MICROSOFT'S C# PROGRAMMING LANGUAGE TO SUN MICROSYSTEMS' JAVA PROGRAMMING LANGUAGE: Metadata Annotations". Dare Obasanjo. Archived from the original on 2012-09-19. Retrieved 2012-09-20.
  4. Coward, Danny (2006-11-02). "JSR 175: A Metadata Facility for the JavaTM Programming Language". Java Community Process . Retrieved 2008-03-05.
  5. "Predefined Annotation Types". Oracle Corporation . Retrieved 2016-12-17.
  6. "The Built-In Annotations : Standard Annotations" . Retrieved 2016-12-17.