Java New Features
Java 9 features, java 8 features, java 7 features, java 4/5 features.
Example to specify annoation for a class
Example to specify annotation for a class, methods or fields.
@Retention annotation is used to specify to what level annotation will be available.
Example to specify the RetentionPolicy
Example of custom annotation: creating, applying and accessing annotation.
Let's see the simple example of creating, applying and accessing annotation.
File: Test.java
How built-in annotaions are used in real scenario?
In real scenario, java programmer only need to apply annotation. He/She doesn't need to create and access annotation. Creating and Accessing annotation is performed by the implementation provider. On behalf of the annotation, java compiler or JVM performs some additional operations.
By default, annotations are not inherited to subclasses. The @Inherited annotation marks the annotation to be inherited to subclasses.
@Documented
The @Documented Marks the annotation for inclusion in the documentation.
- Send your Feedback to [email protected]
Help Others, Please Share
Learn Latest Tutorials
Transact-SQL
Reinforcement Learning
R Programming
React Native
Python Design Patterns
Python Pillow
Python Turtle
Preparation
Verbal Ability
Interview Questions
Company Questions
Trending Technologies
Artificial Intelligence
Cloud Computing
Data Science
Machine Learning
B.Tech / MCA
Data Structures
Operating System
Computer Network
Compiler Design
Computer Organization
Discrete Mathematics
Ethical Hacking
Computer Graphics
Software Engineering
Web Technology
Cyber Security
C Programming
Control System
Data Mining
Data Warehouse
- Java Arrays
- Java Strings
- Java Collection
- Java 8 Tutorial
- Java Multithreading
- Java Exception Handling
- Java Programs
- Java Project
- Java Collections Interview
- Java Interview Questions
- Spring Boot
Annotations in Java
- Inherited Annotations in Java
- Java @Documented Annotations
- Java - @Target Annotations
- Hibernate - Annotations
- The @Override Annotation in Java
- Java @Retention Annotations
- Encapsulation in Java
- The @Deprecated Annotation in Java
- Spring Core Annotations
- Spring Boot - Annotations
- Hibernate - @Lob Annotation
- Hibernate - @MapsId Annotation
- Jackson Annotations For Java Application
- Hibernate - @ManyToMany Annotation
- Comments in Java
- AbstractMap in Java
- Abstract Class in Java
- Kotlin annotations
- Scala | Annotation
Annotations are used to provide supplemental information about a program.
- Annotations start with ‘ @ ’.
- Annotations do not change the action of a compiled program.
- Annotations help to associate metadata (information) to the program elements i.e. instance variables, constructors, methods, classes, etc.
- Annotations are not pure comments as they can change the way a program is treated by the compiler. See below code for example.
- Annotations basically are used to provide additional information, so could be an alternative to XML and Java marker interfaces.
Hierarchy of Annotations in Java
Implementation:
Note: This program throws compiler error because we have mentioned override, but not overridden, we have overloaded display.
Output:
If we remove parameter (int x) or we remove @override, the program compiles fine.
Categories of Annotations
There are broadly 5 categories of annotations as listed:
- Marker Annotations
- Single value Annotations
- Full Annotations
- Type Annotations
- Repeating Annotations
Let us discuss and we will be appending code wherever required if so.
Category 1: Marker Annotations
The only purpose is to mark a declaration. These annotations contain no members and do not consist of any data. Thus, its presence as an annotation is sufficient. Since the marker interface contains no members, simply determining whether it is present or absent is sufficient. @Override is an example of Marker Annotation.
Category 2: Single value Annotations
These annotations contain only one member and allow a shorthand form of specifying the value of the member. We only need to specify the value for that member when the annotation is applied and don’t need to specify the name of the member. However, in order to use this shorthand, the name of the member must be a value.
Category 3: Full Annotations
These annotations consist of multiple data members, names, values, pairs.
Category 4: Type Annotations
These annotations can be applied to any place where a type is being used. For example, we can annotate the return type of a method. These are declared annotated with @Target annotation .
Category 5: Repeating Annotations
These are the annotations that can be applied to a single item more than once. For an annotation to be repeatable it must be annotated with the @Repeatable annotation, which is defined in the java.lang.annotation package. Its value field specifies the container type for the repeatable annotation. The container is specified as an annotation whose value field is an array of the repeatable annotation type. Hence, to create a repeatable annotation, firstly the container annotation is created, and then the annotation type is specified as an argument to the @Repeatable annotation.
Predefined/ Standard Annotations
Java popularly defines seven built-in annotations as we have seen up in the hierarchy diagram.
- Four are imported from java.lang.annotation: @Retention , @Documented , @Target , and @Inherited .
- Three are included in java.lang: @Deprecated, @Override and @SuppressWarnings
Annotation 1: @Deprecated
- It is a marker annotation. It indicates that a declaration is obsolete and has been replaced by a newer form.
- The Javadoc @deprecated tag should be used when an element has been deprecated.
- @deprecated tag is for documentation and @Deprecated annotation is for runtime reflection.
- @deprecated tag has higher priority than @Deprecated annotation when both are together used.
Annotation 2: @Override
It is a marker annotation that can be used only on methods. A method annotated with @Override must override a method from a superclass. If it doesn’t, a compile-time error will result (see this for example). It is used to ensure that a superclass method is actually overridden, and not simply overloaded.
Annotation 3: @SuppressWarnings
It is used to inform the compiler to suppress specified compiler warnings. The warnings to suppress are specified by name, in string form. This type of annotation can be applied to any type of declaration.
Java groups warnings under two categories. They are deprecated and unchecked . Any unchecked warning is generated when a legacy code interfaces with a code that uses generics.
Annotation 4: @Documented
It is a marker interface that tells a tool that an annotation is to be documented. Annotations are not included in ‘Javadoc’ comments. The use of @Documented annotation in the code enables tools like Javadoc to process it and include the annotation type information in the generated document.
Annotation 5: @Target
It is designed to be used only as an annotation to another annotation. @Target takes one argument, which must be constant from the ElementType enumeration. This argument specifies the type of declarations to which the annotation can be applied. The constants are shown below along with the type of the declaration to which they correspond.
We can specify one or more of these values in a @Target annotation. To specify multiple values, we must specify them within a braces-delimited list. For example, to specify that an annotation applies only to fields and local variables, you can use this @Target annotation: @Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE}) @Retention Annotation It determines where and how long the annotation is retent. The 3 values that the @Retention annotation can have:
- SOURCE: Annotations will be retained at the source level and ignored by the compiler.
- CLASS: Annotations will be retained at compile-time and ignored by the JVM.
- RUNTIME: These will be retained at runtime.
Annotation 6: @Inherited
@Inherited is a marker annotation that can be used only on annotation declaration. It affects only annotations that will be used on class declarations. @Inherited causes the annotation for a superclass to be inherited by a subclass. Therefore, when a request for a specific annotation is made to the subclass, if that annotation is not present in the subclass, then its superclass is checked. If that annotation is present in the superclass, and if it is annotated with @Inherited, then that annotation will be returned.
Annotation 7: User-defined (Custom)
User-defined annotations can be used to annotate program elements, i.e. variables, constructors, methods, etc. These annotations can be applied just before the declaration of an element (constructor, method, classes, etc).
Syntax: Declaration
Do keep these certain points as rules for custom annotations before implementing user-defined annotations.
- AnnotationName is an interface.
- The parameter should not be associated with method declarations and throws clause should not be used with method declaration.
- Parameters will not have a null value but can have a default value.
- default value is optional.
- The return type of method should be either primitive, enum, string, class name, or array of primitive, enum, string, or class name type.
Please Login to comment...
Similar reads.
- java-basics
Improve your Coding Skills with Practice
What kind of Experience do you want to share?
Learn Java practically and Get Certified .
Popular Tutorials
Popular examples, reference materials, learn java interactively, java introduction.
- Get Started With Java
- Your First Java Program
- Java Comments
Java Fundamentals
- Java Variables and Literals
- Java Data Types (Primitive)
- Java Operators
- Java Basic Input and Output
- Java Expressions, Statements and Blocks
Java Flow Control
- Java if...else Statement
- Java Ternary Operator
- Java for Loop
- Java for-each Loop
- Java while and do...while Loop
- Java break Statement
- Java continue Statement
- Java switch Statement
- Java Arrays
- Java Multidimensional Arrays
- Java Copy Arrays
Java OOP(I)
- Java Class and Objects
- Java Methods
- Java Method Overloading
- Java Constructors
- Java Static Keyword
- Java Strings
- Java Access Modifiers
- Java this Keyword
- Java final keyword
- Java Recursion
- Java instanceof Operator
Java OOP(II)
Java Inheritance
Java Method Overriding
- Java Abstract Class and Abstract Methods
- Java Interface
- Java Polymorphism
- Java Encapsulation
Java OOP(III)
- Java Nested and Inner Class
- Java Nested Static Class
- Java Anonymous Class
- Java Singleton Class
- Java enum Constructor
- Java enum Strings
- Java Reflection
- Java Package
- Java Exception Handling
- Java Exceptions
- Java try...catch
- Java throw and throws
- Java catch Multiple Exceptions
- Java try-with-resources
Java Annotations
Java Annotation Types
- Java Logging
- Java Assertions
- Java Collections Framework
- Java Collection Interface
- Java ArrayList
- Java Vector
- Java Stack Class
- Java Queue Interface
- Java PriorityQueue
- Java Deque Interface
- Java LinkedList
- Java ArrayDeque
- Java BlockingQueue
- Java ArrayBlockingQueue
- Java LinkedBlockingQueue
- Java Map Interface
- Java HashMap
- Java LinkedHashMap
- Java WeakHashMap
- Java EnumMap
- Java SortedMap Interface
- Java NavigableMap Interface
- Java TreeMap
- Java ConcurrentMap Interface
- Java ConcurrentHashMap
- Java Set Interface
- Java HashSet Class
- Java EnumSet
- Java LinkedHashSet
- Java SortedSet Interface
- Java NavigableSet Interface
- Java TreeSet
- Java Algorithms
- Java Iterator Interface
- Java ListIterator Interface
Java I/o Streams
- Java I/O Streams
- Java InputStream Class
- Java OutputStream Class
- Java FileInputStream Class
- Java FileOutputStream Class
- Java ByteArrayInputStream Class
- Java ByteArrayOutputStream Class
- Java ObjectInputStream Class
- Java ObjectOutputStream Class
- Java BufferedInputStream Class
- Java BufferedOutputStream Class
- Java PrintStream Class
Java Reader/Writer
- Java File Class
- Java Reader Class
- Java Writer Class
- Java InputStreamReader Class
- Java OutputStreamWriter Class
- Java FileReader Class
- Java FileWriter Class
- Java BufferedReader
- Java BufferedWriter Class
- Java StringReader Class
- Java StringWriter Class
- Java PrintWriter Class
Additional Topics
- Java Keywords and Identifiers
- Java Operator Precedence
- Java Bitwise and Shift Operators
- Java Scanner Class
- Java Type Casting
- Java Wrapper Class
- Java autoboxing and unboxing
- Java Lambda Expressions
- Java Generics
- Nested Loop in Java
- Java Command-Line Arguments
Java Tutorials
Java annotations are metadata (data about data) for our program source code.
They provide additional information about the program to the compiler but are not part of the program itself. These annotations do not affect the execution of the compiled program.
Annotations start with @ . Its syntax is:
Let's take an example of @Override annotation.
The @Override annotation specifies that the method that has been marked with this annotation overrides the method of the superclass with the same method name, return type, and parameter list.
It is not mandatory to use @Override when overriding a method. However, if we use it, the compiler gives an error if something is wrong (such as wrong parameter type) while overriding the method.
Example 1: @Override Annotation Example
In this example, the method displayInfo() is present in both the superclass Animal and subclass Dog . When this method is called, the method of the subclass is called instead of the method in the superclass.
- Annotation formats
Annotations may also include elements (members/attributes/parameters).
1. Marker Annotations
Marker annotations do not contain members/elements. It is only used for marking a declaration.
Its syntax is:
Since these annotations do not contain elements, parentheses can be excluded. For example,
2. Single element Annotations
A single element annotation contains only one element.
If there is only one element, it is a convention to name that element as value .
In this case, the element name can be excluded as well. The element name will be value by default.
3. Multiple element Annotations
These annotations contain multiple elements separated by commas.
- Annotation placement
Any declaration can be marked with annotation by placing it above that declaration. As of Java 8, annotations can also be placed before a type.
1. Above declarations
As mentioned above, Java annotations can be placed above class , method , interface , field, and other program element declarations.
Example 2: @SuppressWarnings Annotation Example
If the above program is compiled without using the @SuppressWarnings("unchecked") annotation, the compiler will still compile the program but it will give warnings like:
We are getting the warning
because of the following statement.
This is because we haven't defined the generic type of the array list . We can fix this warning by specifying generics inside angle brackets <> .
2. Type annotations
Before Java 8, annotations could be applied to declarations only. Now, type annotations can be used as well. This means that we can place annotations wherever we use a type.
Constructor invocations
Type definitions
This declaration specifies non-null variable str of type String to avoid NullPointerException .
This declaration specifies a non-null list of type String .
This declaration specifies a list of non-null values of type String .
extends and implements clause
throws clause
Type annotations enable Java code to be analyzed better and provide even stronger type checks.
Types of Annotations
1. Predefined annotations
- @Deprecated
- @SuppressWarnings
- @SafeVarargs
- @FunctionalInterface
2. Meta-annotations
- @Documented
- @Repeatable
3. Custom annotations
These annotation types are described in detail in the Java Annotation Types tutorial.
- Use of Annotations
- Compiler instructions - Annotations can be used for giving instructions to the compiler, detect errors or suppress warnings. The built-in annotations @Deprecated , @Override , @SuppressWarnings are used for these purposes.
- Compile-time instructions - Compile-time instructions provided by these annotations help the software build tools to generate code, XML files and many more.
- Runtime instructions - Some annotations can be defined to give instructions to the program at runtime. These annotations are accessed using Java Reflection.
Table of Contents
- Types of Java Annotations
Sorry about that.
Related Tutorials
Java Tutorial
- Watch & Listen
- Oracle University
Annotations
Annotations have a number of uses, among them:
- Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
- Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
- Runtime processing — Some annotations are available to be examined at runtime.
This section explains where annotations can be used, how to apply annotations, what predefined annotation types are available in the Java Platform, Standard Edition (Java SE API), how type annotations can be used in conjunction with pluggable type systems to write code with stronger type checking, and how to implement repeating annotations.
The Format of an Annotation
In its simplest form, an annotation looks like the following:
The at sign character ( @ ) indicates to the compiler that what follows is an annotation. In the following example, the annotation's name is Override :
The annotation can include elements , which can be named or unnamed, and there are values for those elements:
If there is just one element named value , then the name can be omitted, as in:
If the annotation has no elements, then the parentheses can be omitted, as shown in the previous @Override example.
It is also possible to use multiple annotations on the same declaration:
If the annotations have the same type, then this is called a repeating annotation:
Repeating annotations are supported as of the Java SE 8 release. For more information, see the section Repeating Annotations.
The annotation type can be one of the types that are defined in the java.lang or java.lang.annotation packages of the Java SE API. In the previous examples, Override and SuppressWarnings are predefined Java annotations. It is also possible to define your own annotation type. The Author and Ebook annotations in the previous example are custom annotation types.
Where Annotations Can Be Used
Annotations can be applied to declarations: declarations of classes, fields, methods, and other program elements. When used on a declaration, each annotation often appears, by convention, on its own line.
As of the Java SE 8 release, annotations can also be applied to the use of types. Here are some examples:
Class instance creation expression:
implements clause:
Thrown exception declaration:
This form of annotation is called a type annotation .
Declaring an Annotation Type
Many annotations replace comments in code.
Suppose that a software group traditionally starts the body of every class with comments providing important information:
To add this same metadata with an annotation, you must first define the annotation type. The syntax for doing this is:
The annotation type definition looks similar to an interface definition where the keyword interface is preceded by the at sign ( @ ) ( @ = AT, as in annotation type). Annotation types are a form of interface, which will be covered in a later section. For the moment, you do not need to understand interfaces.
The body of the previous annotation definition contains annotation type element declarations, which look a lot like methods. Note that they can define optional default values.
After the annotation type is defined, you can use annotations of that type, with the values filled in, like this:
Note: To make the information in @ClassPreamble appear in Javadoc-generated documentation, you must annotate the @ClassPreamble definition with the @Documented annotation:
Predefined Annotation Types
A set of annotation types are predefined in the Java SE API. Some annotation types are used by the Java compiler, and some apply to other annotations.
Annotation Types Used by the Java Language
The predefined annotation types defined in java.lang are @Deprecated , @Override , and @SuppressWarnings .
@Deprecated
@Deprecated annotation indicates that the marked element is deprecated and should no longer be used. The compiler generates a warning whenever a program uses a method, class, or field with the @Deprecated annotation. When an element is deprecated, it should also be documented using the Javadoc @deprecated tag, as shown in the following example. The use of the at sign ( @ ) in both Javadoc comments and in annotations is not coincidental: they are related conceptually. Also, note that the Javadoc tag starts with a lowercase d and the annotation starts with an uppercase D .
Note that, as of Java SE 9, a forRemoval attribute has been added to the @Deprecated annotation. It indicates whether the annotated element is subject to removal in a future version. The default value is false .
@Override annotation informs the compiler that the element is meant to override an element declared in a superclass. Overriding methods will is discussed in the section Interfaces and Inheritance.
While it is not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with @Override fails to correctly override a method in one of its superclasses, the compiler generates an error.
@SuppressWarnings
@SuppressWarnings annotation tells the compiler to suppress specific warnings that it would otherwise generate. In the following example, a deprecated method is used, and the compiler usually generates a warning. In this case, however, the annotation causes the warning to be suppressed.
Every compiler warning belongs to a category. The Java Language Specification lists two categories: deprecation and unchecked. The unchecked warning can occur when interfacing with legacy code written before the advent of generics. To suppress multiple categories of warnings, use the following syntax:
@SafeVarargs
@SafeVarargs annotation, when applied to a method or constructor, asserts that the code does not perform potentially unsafe operations on its varargs parameter. When this annotation type is used, unchecked warnings relating to varargs usage are suppressed.
@FunctionalInterface
@FunctionalInterface annotation, introduced in Java SE 8, indicates that the type declaration is intended to be a functional interface, as defined by the Java Language Specification.
Annotations That Apply to Other Annotations
Annotations that apply to other annotations are called meta-annotations. There are several meta-annotation types defined in java.lang.annotation .
@Retention annotation specifies how the marked annotation is stored:
- RetentionPolicy.SOURCE – The marked annotation is retained only in the source level and is ignored by the compiler.
- RetentionPolicy.CLASS – The marked annotation is retained by the compiler at compile time, but is ignored by the Java Virtual Machine (JVM).
- RetentionPolicy.RUNTIME – The marked annotation is retained by the JVM so it can be used by the runtime environment.
@Documented
@Documented annotation indicates that whenever the specified annotation is used those elements should be documented using the Javadoc tool. (By default, annotations are not included in Javadoc.) For more information, see the Javadoc tools page.
@Target annotation marks another annotation to restrict what kind of Java elements the annotation can be applied to. A target annotation specifies one of the following element types as its value:
- ElementType.ANNOTATION_TYPE can be applied to an annotation type.
- ElementType.CONSTRUCTOR can be applied to a constructor.
- ElementType.FIELD can be applied to a field or property.
- ElementType.LOCAL_VARIABLE can be applied to a local variable.
- ElementType.METHOD can be applied to a method-level annotation.
- ElementType.MODULE can be applied to a module declaration.
- ElementType.PACKAGE can be applied to a package declaration.
- ElementType.PARAMETER can be applied to the parameters of a method.
- ElementType.RECORD_COMPONENT can be applied to the component of a record.
- ElementType.TYPE can be applied to the declaration of a class, an abtract class, an interface, an annotation interface, an enumeration, or a record declaration.
- ElementType.TYPE_PARAMETER can be applied on the parameters of a type.
- ElementType.TYPE_USE can be applied where a type is used, for instance on the declaration of a field.
@Inherited annotation indicates that the annotation type can be inherited from the super class. (This is not true by default.) When the user queries the annotation type and the class has no annotation for this type, the class' superclass is queried for the annotation type. This annotation applies only to class declarations.
@Repeatable
@Repeatable annotation, introduced in Java SE 8, indicates that the marked annotation can be applied more than once to the same declaration or type use. For more information, see the section Repeating Annotations.
Type Annotations and Pluggable Type Systems
Before the Java SE 8 release, annotations could only be applied to declarations. As of the Java SE 8 release, annotations can also be applied to any type use. This means that annotations can be used anywhere you use a type. A few examples of where types are used are class instance creation expressions ( new ), casts, implements clauses, and throws clauses. This form of annotation is called a type annotation and several examples are provided in the section Annotations Basics.
Type annotations were created to support improved analysis of Java programs way of ensuring stronger type checking. The Java SE 8 release does not provide a type checking framework, but it allows you to write (or download) a type checking framework that is implemented as one or more pluggable modules that are used in conjunction with the Java compiler.
For example, you want to ensure that a particular variable in your program is never assigned to null; you want to avoid triggering a NullPointerException . You can write a custom plug-in to check for this. You would then modify your code to annotate that particular variable, indicating that it is never assigned to null. The variable declaration might look like this:
When you compile the code, including the NonNull module at the command line, the compiler prints a warning if it detects a potential problem, allowing you to modify the code to avoid the error. After you correct the code to remove all warnings, this particular error will not occur when the program runs.
You can use multiple type-checking modules where each module checks for a different kind of error. In this way, you can build on top of the Java type system, adding specific checks when and where you want them.
With the judicious use of type annotations and the presence of pluggable type checkers, you can write code that is stronger and less prone to error.
In many cases, you do not have to write your own type checking modules. There are third parties who have done the work for you. For example, you might want to take advantage of the Checker Framework created by the University of Washington. This framework includes a NonNull module, as well as a regular expression module, and a mutex lock module. For more information, see the Checker Framework .
Repeating Annotations
There are some situations where you want to apply the same annotation to a declaration or type use. As of the Java SE 8 release, repeating annotations enable you to do this.
For example, you are writing code to use a timer service that enables you to run a method at a given time or on a certain schedule, similar to the UNIX cron service. Now you want to set a timer to run a method, doPeriodicCleanup() , on the last day of the month and on every Friday at 11:00 p.m. To set the timer to run, create an @Schedule annotation and apply it twice to the doPeriodicCleanup() method. The first use specifies the last day of the month and the second specifies Friday at 11p.m., as shown in the following code example:
The previous example applies an annotation to a method. You can repeat an annotation anywhere that you would use a standard annotation. For example, you have a class for handling unauthorized access exceptions. You annotate the class with one @Alert annotation for managers and another for admins:
For compatibility reasons, repeating annotations are stored in a container annotation that is automatically generated by the Java compiler. In order for the compiler to do this, two declarations are required in your code.
Step 1: Declare a Repeatable Annotation Type
The annotation type must be marked with the @Repeatable meta-annotation. The following example defines a custom @Schedule repeatable annotation type:
The value of the @Repeatable meta-annotation, in parentheses, is the type of the container annotation that the Java compiler generates to store repeating annotations. In this example, the containing annotation type is @Schedules , so repeating @Schedule annotations is stored in an @Schedules annotation.
Applying the same annotation to a declaration without first declaring it to be repeatable results in a compile-time error.
Step 2: Declare the Containing Annotation Type
The containing annotation type must have a value element with an array type. The component type of the array type must be the repeatable annotation type. The declaration for the @Schedules containing annotation type is the following:
Retrieving Annotations
There are several methods available in the Reflection API that can be used to retrieve annotations. The behavior of the methods that return a single annotation, such as AnnotatedElement.getAnnotation(Class<T>) , are unchanged in that they only return a single annotation if one annotation of the requested type is present. If more than one annotation of the requested type is present, you can obtain them by first getting their container annotation. In this way, legacy code continues to work. Other methods were introduced in Java SE 8 that scan through the container annotation to return multiple annotations at once, such as AnnotatedElement.getAnnotationsByType(Class<T>) . See the AnnotatedElement class specification for information on all of the available methods.
Design Considerations
When designing an annotation type, you must consider the cardinality of annotations of that type. It is now possible to use an annotation zero times, once, or, if the annotation's type is marked as @Repeatable , more than once. It is also possible to restrict where an annotation type can be used by using the @Target meta-annotation. For example, you can create a repeatable annotation type that can only be used on methods and fields. It is important to design your annotation type carefully to ensure that the programmer using the annotation finds it to be as flexible and powerful as possible.
In this tutorial
Last update: September 14, 2021
- Books Get Your Hands Dirty on Clean Architecture Stratospheric
- Contribute Become an Author Writing Guide Author Workflow Author Payment
- Services Book me Advertise
- Categories Spring Boot Java Node Kotlin AWS Software Craft Simplify! Meta Book Reviews
An Introduction to Annotations and Annotation Processing in Java
- February 5, 2022
An annotation is a construct associated with Java source code elements such as classes, methods, and variables. Annotations provide information to a program at compile time or at runtime based on which the program can take further action. An annotation processor processes these annotations at compile time or runtime to provide functionality such as code generation, error checking, etc.
The java.lang package provides some core annotations and also gives us the capability to create our custom annotations that can be processed with annotation processors.
In this article, we will discuss the topic of annotations and demonstrate the power of annotation processing with a real-world example.
Example Code
Annotation basics.
An annotation is preceded by the @ symbol. Some common examples of annotations are @Override and @SuppressWarnings . These are built-in annotations provided by Java through the java.lang package. We can further extend the core functionality to provide our custom annotations.
An annotation by itself does not perform any action. It simply provides information that can be used at compile time or runtime to perform further processing.
Let’s look at the @Override annotation as an example:
We use the @Override annotation to mark a method that exists in a parent class, but that we want to override in a child class. The above program throws an error during compile time because the getname() method in ChildClass is annotated with @Override even though it doesn’t override a method from ParentClass (because there is no getname() method in ParentClass ).
By adding the @Override annotation in ChildClass , the compiler can enforce the rule that the overriding method in the child class should have the same case-sensitive name as that in the parent class, and so the program would throw an error at compile time, thereby catching an error which could have gone undetected even at runtime.
Standard Annotations
Below are some of the most common annotations available to us. These are standard annotations that Java provides as part of the java.lang package. To see their full effect it would be best to run the code snippets from the command line since most IDEs provide their custom options that alter warning levels.
@SuppressWarnings
We can use the @SuppressWarnings annotation to indicate that warnings on code compilation should be ignored. We may want to suppress warnings that clutter up the build output. @SuppressWarnings("unchecked") , for example, suppresses warnings associated with raw types.
Let’s look at an example where we might want to use @SuppressWarnings :
If we run this program from the command-line using the compiler switch -Xlint:unchecked to receive the full warning list, we get the following message:
The above code-block is an example of legacy Java code (before Java 5), where we could have collections in which we could accidentally store mixed types of objects. To introduce compile time error checking generics were introduced. So to get this legacy code to compile without error we would change:
If we had a large legacy code base, we wouldn’t want to go in and make lots of code changes since it would mean a lot of QA regression testing. So we might want to add the @SuppressWarning annotation to the class so that the logs are not cluttered up with redundant warning messages. We would add the code as below:
Now if we compile the program, the console is free of warnings.
@Deprecated
We can use the @Deprecated annotation to mark that a method or type has been replaced with newer functionality.
IDEs make use of annotation processing to throw a warning at compile time, usually indicating the deprecated method with a strike-through to tell the developer that they shouldn’t use this method or type anymore.
The following class declares a deprecated method:
The attribute since in the annotation tells us in which version the element was deprecated, and forRemoval indicates if the element is going to be removed in the next version.
Now, calling the legacy method as below will trigger a compile time warning indicating that the method call needs to be replaced:
We already had a look at the @Override annotation above. We can use it to indicate that a method will be overriding the method with the same signature in a parent class. It is used to throw compile time errors in cases such as typos in letter-casing as in this code example:
We intended to override the getEmployeeStatus() method but we misspelled the method name. This can lead to serious bugs. The program above would compile and run without issue without catching that bug.
If we add the annotation @Override to the getemployeeStatus() method, we get a compile time error, which causes a compile error and forces us to correct the typo right away:
@FunctionalInterface
The @FunctionalInterface annotation is used to indicate that an interface cannot have more than one abstract method. The compiler throws an error in case there is more than one abstract method. Functional interfaces were introduced in Java 8, to implement Lambda expressions and to ensure that they didn’t make use of more than one method.
Even without the @FunctionalInterface annotation, the compiler will throw an error if you include more than one abstract method in the interface. So why do we need @FunctionalInterface if it is not mandatory?
Let us take the example of the code below:
If we add another method printString2() to the Print interface, the compiler or the IDE will throw an error and this will be obvious right away.
Now, what if the Print interface was in a separate module, and there was no @FunctionalInterface annotation? The developers of that other module could easily add another function to the interface and break your code. Further, now we have to figure out which of the two is the right function in our case. By adding the @FunctionalInterface annotation we get an immediate warning in the IDE, such as this:
So it is good practice to always include the @FunctionalInterface if the interface should be usable as a Lambda.
@SafeVarargs
The varargs functionality allows the creation of methods with variable arguments. Before Java 5, the only option to create methods with optional parameters was to create multiple methods, each with a different number of parameters. Varargs allows us to create a single method to handle optional parameters with syntax as below:
However, warnings are thrown when generics are used in the arguments. @SafeVarargs allows for suppression of these warnings:
In the above code, printString() and printStringVarargs() achieve the same result. Compiling the code, however, produces a warning for printStringSafeVarargs() since it used generics:
By adding the SafeVarargs annotation as below, we can get rid of the warning:
Custom Annotations
These are annotations that are custom-created to serve a particular purpose. We can create them ourselves. We can use custom annotations to
- reduce repetition,
- automate the generation of boilerplate code,
- catch errors at compile time such as potential null pointer checks,
- customize runtime behavior based on the presence of a custom annotation.
An example of a custom annotation would be this @Company annotation:
When creating multiple instances of the CustomAnnotatedEmployee class, all instances would contain the same company name and city , so wouldn’t need to add that information to the constructor anymore.
To create a custom annotation we need to declare it with the @interface keyword:
To specify information about the scope of the annotation and the area it targets, such as compile time or runtime, we need to add meta annotations to the custom annotation.
For example, to specify that the annotation applies to classes only, we need to add @Target(ElementType.TYPE) , which specifies that this annotation only applies to classes, and @Retention(RetentionPolicy.RUNTIME) , which specifies that this annotation must be available at runtime. We will discuss further details about meta annotations once we get this basic example running.
With the meta annotations, our annotation looks like this:
Next, we need to add the fields to the custom annotation. In this case, we need name and city . So we add it as below:
Putting it all together, we can create a CustomAnnotatedEmployee class and apply the annotation to it as below:
Now we can create a test class to read the @Company annotation at runtime:
This would give the output below:
So by introspecting the annotation at runtime we can access some common information of all employees and avoid a lot of repetition if we had to construct a lot of objects.
Meta Annotations
Meta annotations are annotations applied to other annotations that provide information about the annotation to the compiler or the runtime environment.
Meta annotations can answer the following questions about an annotation:
- Can the annotation be inherited by child classes?
- Does the annotation need to show up in the documentation?
- Can the annotation be applied multiple times to the same element?
- What specific element does the annotation apply to, such as class, method, field, etc.?
- Is the annotation being processed at compile time or runtime?
By default, an annotation is not inherited from a parent class to a child class. Applying the @Inherited meta annotation to an annotation allows it to be inherited:
Since CustomAnnotatedEmployee has the @Company annotation and CustomAnnotatedManager inherits from it, the CustomAnnotatedManager class does not need to include it.
Now if we run the test for the Manager class, we still get access to the annotation information, even though the Manager class does not have the annotation:
@Documented
@Documented ensures that custom annotations show up in the JavaDocs.
Normally, when we run JavaDoc on the class CustomAnnotatedManager the annotation information would not show up in the documentation. But when we use the @Documented annotation, it will:
@Repeatable
@Repeatable allows multiple repeating custom annotations on a method, class, or field. To use the @Repeatable annotation we need to wrap the annotation in a container class which refers to it as an array:
We declare our main class as below:
If we run a test on it as below:
We get the following output which displays the value of multiple @RepeatableCompany annotations:
@Target specifies on which elements the annotation can be used, for example in the above example the annotation @Company was defined only for TYPE and so it could only be applied to a class.
Let’s see what happens if we apply the @Company annotation to a method:
If we applied the @Company annotation to the method getEmployeeStatus() as above, we get a compiler error stating: '@Company' not applicable to method.
The various self-explanatory target types are:
- ElementType.ANNOTATION_TYPE
- ElementType.CONSTRUCTOR
- ElementType.FIELD
- ElementType.LOCAL_VARIABLE
- ElementType.METHOD
- ElementType.PACKAGE
- ElementType.PARAMETER
- ElementType.TYPE
@Retention specifies when the annotation is discarded.
SOURCE - The annotation is used at compile time and discarded at runtime.
CLASS - The annotation is stored in the class file at compile time and discarded at run time.
RUNTIME - The annotation is retained at runtime.
If we needed an annotation to only provide error checking at compile time as @Override does, we would use SOURCE . If we need an annotation to provide functionality at runtime such as @Test in Junit we would use RUNTIME . To see a real example, create the following annotations in 3 separate files:
Now create a class that uses all 3 annotations:
To verify that only the runtime annotation is available at runtime, run a test as follows:
The output would be as follows:
So we verified that only the RUNTIME annotation gets processed at runtime.
Annotation Categories
Annotation categories distinguish annotations based on the number of parameters that we pass into them. By categorizing annotations as parameter-less, single value, or multi-value, we can more easily think and talk about annotations.
Marker Annotations
Marker annotations do not contain any members or data. We can use the isAnnotationPresent() method at runtime to determine the presence or absence of a marker annotation and make decisions based on the presence of the annotation.
For example, if our company had several clients with different data transfer mechanisms, we could annotate the class with an annotation indicating the method of data transfer as below:
The client class could use the annotation as below:
We can process the annotation as follows:
Based on whether the @CSV annotation exists or not, we can decide whether to write out the information to CSV or an Excel file. The above program would produce this output:
Single-Value Annotations
Single-value annotations contain only one member and the parameter is the value of the member. The single member has to be named value .
Let’s create a SingleValueAnnotationCompany annotation that uses only the value field for the name, as below:
Create a class that uses the annotation as below:
Run a test as below:
The single value ‘XYZ’ overrides the default annotation value and the output is as below:
Full Annotations
They consist of multiple name value pairs. For example Company(name="ABC", city="XYZ") . Considering our original Company example:
Let’s create the MultiValueAnnotatedEmployee class as below. Specify the parameters and values as below. The default values will be overwritten.
The output is as below, and has overridden the default annotation values:
Building a Real-World Annotation Processor
For our real-world annotation processor example, we are going to do a simple simulation of the annotation @Test in JUnit. By marking our functions with the @Test annotation we can determine at runtime which of the methods in a test class need to be run as tests.
We first create the annotation as a marker annotation for methods:
Next, we create a class AnnotatedMethods , to which we will apply the @Test annotations to the method test1() . This will enable the method to be executed at runtime. The method test2() does not have an annotation, and should not be executed at runtime.
Now we create the test to run the AnnotatedMethods class:
By calling getDeclaredMethods() , we’re getting the methods of our AnnotatedMethods class. Then, we’re iterating through the methods and checking each method if it is annotated with the @Test annotation. Finally, we perform a runtime invocation of the methods that were identified as being annotated with @Test .
We want to verify the test1() method will run since it is annotated with @Test , and test2() will not run since it is not annotated with @Test .
The output is:
So we verified that test2() , which did not have the @Test annotation, did not have its output printed.
We did an overview of annotations, followed by a simple real-world example of annotation processing.
We can further use the power of annotation processing to perform more complex automated tasks such as creating builder source files for a set of POJOs at compile time. A builder is a design pattern in Java that is used to provide a better alternative to constructors when there is a large number of parameters involved or there is a need for multiple constructors with optional parameters. If we had a few dozen POJOs, the code generation capabilities of the annotation processor would save us a lot of time by creating the corresponding builder files at compile time.
By fully leveraging the power of annotation processing we will be able to skip a lot of repetition and save a lot of time.
You can play around with the code examples from this article on GitHub .
Arshad Syed
As a software developer I am always interested in learning new technologies. I am currently working on improving my full stack skills, and also on teaching technology.
Recent Posts
Apache HttpClient Configuration
- May 29, 2024
Configuring Apache HttpClient is essential for tailoring its behavior to meet specific requirements and optimize performance. From setting connection timeouts to defining proxy settings, configuration options allow developers to fine-tune the client’s behavior according to the needs of their application.
Async APIs Offered by Apache HttpClient
In this article, we are going to learn about the async APIs offered by Apache HttpClient. We are going to explore the different ways Apache HttpClient enables developers to send and receive data over the internet in asynchronous mode.
Classic APIs Offered by Apache HttpClient
In this article, we are going to learn about the classic APIs offered by Apache HttpClient. We are going to explore the different ways Apache HttpClient helps us to send and receive data over the internet in classic (synchronous) mode.
- Enterprise Java
- Web-based Java
- Data & Java
- Project Management
- Visual Basic
- Ruby / Rails
- Java Mobile
- Architecture & Design
- Open Source
- Web Services
Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More .
In Java, annotations are metadata that are applied to classes, interfaces, methods, or fields in order to provide additional information about the program to the compiler. In other words, annotations offer a way to give metadata information about a certain program construct, like classes, methods, variables, and so forth.
In today’s Java programming tutorial, we will look at how to use the different types of annotations in Java, alongside providing some coding examples to make the learning process easier.
Read: Tips to Improve Performance in Java
What is a Java Annotation?
Annotations can be used to add metadata to your code, and typically appear before a method or variable definition. Annotations do not modify the structure of your program or its behavior; rather, they allow you to easily add contextual information about an element in source code.
Annotation is a form of metadata that gives supplementary information about elements in source code. Annotations are a powerful feature of the Java language that can make your code more readable and easier to maintain. Java annotations were first introduced in JDK 5.0 and have since become an integral part of the Java language.
As stated, an annotation is a way to provide metadata about a Java element. They are used for a variety of purposes, including:
- Compiler directives
- Code generation
- Runtime processing
Java annotations are also a way of adding metadata to Java code. They can be used for a variety of purposes, such as specifying configuration information, documenting code, and providing information that can be used by tools.
For instance, annotations can be used to indicate that a method is deprecated, or to generate warnings if a method is called that should no longer be used. This metadata can be used by tools to generate documentation, or to automatically configure systems.
Benefits of Annotations in Java
Annotation metadata can be used by the compiler to generate code, or it can be used at runtime to introspect the code. Annotations can be used to mark methods, fields, classes, and other elements of the Java language.
There are many reasons why annotations are needed. One reason is that they provide a way to add information to the Java code that is not part of the code itself. This information can be used by tools that process the code, such as IDEs, build tools, and so on.
Another reason for annotations is that they can be used to introspect the code at runtime. This can be useful for debugging, or for creating dynamic applications that need to access information about the structure of the code at runtime.
Another benefits of annotations make your code easy to understand, maintain and reuse and improve the readability of your code.
Finally, annotations can be used as a way to specify configuration information for applications. For example, an annotation could be used to specify that a particular class should be exposed as a web service.
Read: Working with the Java Logging API
Java Standard Annotations
Annotations in Java are a powerful tool that can be used to improve the quality of your code. They can be used to add information about the code, to specify dependencies, and to enforce rules.
- @Override : You can take advantage of this annotation to specify that a method of a child class has overridden a superclass method. This is important because it can help to avoid errors when upgrading code to new versions of libraries.
- @Deprecated: This annotation is used to mark methods and classes as deprecated. This is useful for indicating that code should no longer be used, and it can also help to provide guidance on how to replace deprecated code.
- @SuppressWarnings : This annotation is used to suppress warnings from the compiler. This can be useful when you want to temporarily disable warnings so that you can focus on other parts of the code.
Types of Annotations in Java
There are five types of annotations in Java:
- Marker Annotations
Single-Value Annotations
Type annotations, full annotations, repeatable annotations.
Let’s take a closer look at each type of annotation.
Marker Annotations in Java
A marker annotation does not have any values associated with it. An example of a marker annotation is @Override , which is used to indicate that a method is overriding a method from a superclass.
A single-value annotation has one value associated with it. An example of a single-value annotation is @Deprecated , which is used to mark a class, field, or method as deprecated. Deprecated means that the element should no longer be used and might be removed in future versions.
Type Annotations are used wherever a type has been used. For example, you can use it to annotate the return type of a method.
Full Annotations in Java comprise of several data members, values, names, pairs.
Repeating Annotations in Java are those that can be applied to an item more than once.
Read: The Top Java IDEs
Use Cases for Java Annotations
Java annotations can be used in a number of ways, such as:
- To specify configuration information for a class or method
- To document code
- To create unit tests
- To generate source code
- To provide information that can be used by tools
How to Program Annotations in Java
When you create an annotation type, you must specify the elements that it contains. For each element, you must specify its name and whether or not it’s required. You can also specify the default value for an element if one is not provided.
The following code listing illustrates how you can take advantage of annotations in Java:
Final Thoughts on Annotations in Java
When used correctly, Java annotations are very useful. Annotating your code makes it easier to read and maintain. In addition, annotations can be used to generate documentation or to enforce certain rules at compile time. If you are not using annotations in your Java code, you should consider doing so, now.
Read more Java programming tutorials and Java software development guides .
Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
Latest Posts
What is the role of a project manager in software development, how to use optional in java, overview of the jad methodology, microsoft project tips and tricks, how to become a project manager in 2023, related stories, understanding types of thread synchronization errors in java, understanding memory consistency in java threads.
- Manage Email Subscriptions
- How to Post to DZone
- Article Submission Guidelines
- Manage My Drafts
Cloud Native : How are orgs leveraging a cloud-centric state of development that allow their applications to remain resilient and scalable?
Join our Cloud Native Virtual Roundtable where, alongside great panelists, we'll dive into the essential pillars of cloud-native technology.
Launch your software development career: Dive head first into the SDLC and learn how to build high-quality software and teams.
AI Automation Essentials . Check out this Refcard for all things AI automation, including model training, data security, and more.
- Java, Spring Boot, and MongoDB: Performance Analysis and Improvements
- How to Use Java to Build Single Sign-on
- Dependency Injection in Spring
- 4 Spring Annotations Every Java Developer Should Know
- Profiling Big Datasets With Apache Spark and Deequ
- Less Time Learning, More Time Building
- How to Quickly Create and Easily Configure a Local Redis Cluster
- Building Robust ML Systems: Best Practices for Production
How Do Annotations Work in Java?
Grab some coffee and get ready to dive into the world of annotations..
Join the DZone community and get the full member experience.
Annotations have been a very important part of Java, and it’s been there from the time of J2SE 5.0. All of us have seen annotations like @Override and @Deprecated in our application code at some place or another. In this article, I will discuss what exactly annotations are, why they were introduced, how they work, how to write custom annotations (with example code), what could be valid scenarios for annotations, and lastly annotations and ADF. It’s going to be a long post, so grab some coffee and get ready to dive into the world of annotations.
What Are Annotations?
One word to explain annotation is metadata . Metadata is data about data. So annotations are metadata for code. For example, look at the following piece of code.
Annotation is a special kind of Java construct used to decorate a class, method, field, parameter, variable, constructor, or package. It’s the vehicle chosen by JSR-175 to provide metadata.
Why Were Annotations Introduced?
Prior to annotation (and even after), XML was extensively used for metadata, and somehow, a particular set of Application Developers and Architects thought XML maintenance was getting troublesome. They wanted something that could be coupled closely with code instead of XML, which is very loosely coupled (in some cases, almost separate) from code. If you google “XML vs. annotations”, you will find a lot of interesting debates. An interesting point is that XML configurations were introduced to separate configurations from code. The last two statements might create a bit of doubt in your mind that these two are creating a cycle, but both have their pros and cons. Let’s try to understand with an example.
Suppose, you want to set some application-wide constants/parameters. In this scenario, XML would be a better choice because this is not related to any specific piece of code. If you want to expose some method as a service, an annotation would be a better choice as it needs to be tightly coupled with that method and developer of the method must be aware of this.
Another important factor is that an annotation defines a standard way of defining metadata in code. Prior to annotations, people also used their own ways to define metadata. Some examples are using marker interfaces, comments, transient keywords, etc. Each developer needs his own way to decide metadata, but annotation standardized things.
These days most frameworks use a combination of both XML and Annotations to leverage positive aspects of both.
How Annotations Work and How to Write Custom Annotations
Before I start this explanation, I will suggest you download this sample code for annotations ( AnnotationsSample.zip ) and keep that open in any IDE of your choice, as it will help you to understand following explanation better.
Writing annotations is very simple. You can compare annotation definition to an interface definition. Let’s have a look at two examples — one is the standard @Override annotation and the second is a custom annotation @Todo :
Something seems fishy about @Override ; it’s not doing anything — it simply checks to see if a method is defined in the parent class. Well, don’t be surprised; I am not kidding you. Override annotation’s definition has that much code only. This is the most important part to understand, and I am reiterating myself: Annotations are only metadata and do not contain any business logic . Tough to digest but true. If annotations do not contain the logic, then someone else must be doing something and that someone is the consumer of this annotation metadata. Annotations only provide information about the attribute (class/method/package/field) on which it is defined. The consumer is a piece of code that reads this information and then performs the necessary logic.
When we are talking about standard annotations like @Override , the JVM is the consumer and it works at the bytecode level. Now that’s something application developers can’t control and can’t use for custom annotations. So we need to write to consumers for our annotations by ourselves.
Let’s understand the key terms used for writing annotations one by one. In the above examples, you will see annotations are used on annotations.
J2SE 5.0 provides four annotations in the java.lang.annotation package that are used only when writing annotations:
@Documented – Whether to put the annotation in Javadocs @Retention – When the annotation is needed @Target? – Places the annotation can go @Inherited – Whether subclasses get the annotation.
@Documented – A simple market annotation that tells whether to add an annotation in the Java doc or not.
@Retention – Defines how long the annotation should be kept.
RetentionPolicy.SOURCE – Discard during the compile. These annotations don’t make any sense after the compile has completed, so they aren’t written to the bytecode. Examples: @Override , @SuppressWarnings
RetentionPolicy.CLASS – Discard during class load. Useful when doing bytecode-level post-processing. Somewhat surprisingly, this is the default.
RetentionPolicy.RUNTIME – Do not discard. The annotation should be available for reflection at runtime. This is what we generally use for our custom annotations.
@Target – Where annotation can be placed. If you don’t specify this, annotation can be placed anywhere. The following are valid values. One important point here is that it’s inclusive only, which means if you want annotation on 7 attributes and just want to exclude only one attribute, you need to include all 7 while defining the target.
ElementType.TYPE (class, interface, enum) ElementType.FIELD (instance variable) ElementType.METHOD ElementType.PARAMETER ElementType.CONSTRUCTOR ElementType.LOCAL_VARIABLE ElementType.ANNOTATION_TYPE (on another annotation) ElementType.PACKAGE (remember package-info.java)
@Inherited – Controls whether the annotation should affect the subclass.
Now, what goes inside an annotation definition? Annotations only support primitives, string, and enumerations. All attributes of annotations are defined as methods, and default values can also be provided
The following is an example of how the above annotation can be used:
If we have only one attribute inside an annotation, it should be named “value” and can be used without attribute name while using it.
So far so good. We have defined our custom annotation and applied it to some business logic methods. Now, it’s time to write a consumer. For that, we will need to use Reflection. If you are familiar with Reflection code, you know reflection provides Class, Method and Field objects. All of these have a getAnnotation() method, which returns the annotation object. We need to cast this object as our custom annotation (after checking with instanceOf() ) and then, we can call methods defined in our custom annotation. Let’s look at the sample code, which uses the above annotation:
Use Cases for Annotations
Annotations are very powerful, and frameworks like Spring and Hibernate use annotations very extensively for logging and validations. Annotations can be used in places where marker interfaces are used. Marker interfaces are for the complete class but you can define annotations that could be used on individual methods, for example, whether a certain method is exposed as service method or not.
In the servlet specification 3.0, a lot of annotations were introduced, especially related to servlet security. Let's check out a few:
HandlesTypes – This annotation is used to declare an array of application classes which are passed to a ServletContainerInitializer .
HttpConstraint – This annotation represents the security constraints that are applied to all requests with HTTP protocol method types that are not otherwise represented by a corresponding HttpMethodConstraint in a ServletSecurity annotation.
HttpMethodConstraint – Specific security constraints can be applied to different types of request, differentiated by the HTTP protocol method type by using this annotation inside the ServletSecurity annotation.
MultipartConfig – This annotation is used to indicate that the Servlet on which it is declared expects requests to made using the multipart/form-data MIME type.
ServletSecurity – Declare this annotation on a Servlet implementation class to enforce security constraints on HTTP protocol requests.
WebFilter – The annotation used to declare a Servlet Filter.
WebInitParam – The annotation used to declare an initialization parameter on a Servlet or Filter, within a WebFilter or WebServlet annotation.
WebListener — The annotation used to declare a listener for various types of event, in a given web application context.
WebServlet – This annotation is used to declare the configuration of a Servlet.
ADF (Application Development Framework) and Annotations
Now, we are in the last part of our discussion: the Application Development Framework, also known as ADF. The ADF is developed by Oracle and used to build Oracle Fusion Applications. We have seen pros and cons, and we know how to write custom annotations, but where can we use custom annotations in ADF? Does ADF provide any native annotations?
These are certainly interesting questions: But are there certain limitations that prevent the usage of annotations on a large scale in ADF? Frameworks, which were mentioned earlier, like Spring and Hibernate, use AOP (aspect-oriented programming). In AOP, the framework provides a mechanism to inject code for preProcessing and postProcessing for any event. For example, you have a hook to place code before and after a method execution, so you can write your consumer code in those places. ADF does not use AOP. If we have any valid use case for annotations, we might need to go via the inheritance way.
Hope you enjoyed this article. Please drop your thoughts in the comments!
Originally published August 2015
Further Reading
Creating Annotations
A Guide to Spring Framework Annotations
5 Annotations Every Java Developer Should Know
Published at DZone with permission of Yashwant Golecha , DZone MVB . See the original article here.
Opinions expressed by DZone contributors are their own.
Partner Resources
- About DZone
- Send feedback
- Community research
- Advertise with DZone
CONTRIBUTE ON DZONE
- Become a Contributor
- Core Program
- Visit the Writers' Zone
- Terms of Service
- Privacy Policy
- 3343 Perimeter Hill Drive
- Nashville, TN 37211
- [email protected]
Let's be friends:
Table of Contents
Hierarchy of annotations in java, categories of annotations, types of annotations, use of annotations, annotations in java: explained with examples.
Annotations in Java provide additional information to the compiler and JVM . An annotation is a tag representing metadata about classes , interfaces , variables, methods , or fields. Annotations do not impact the execution of the code that they annotate. Some of the characteristics of annotations are:
- Begin with ‘@’
- Do not alter the execution of the program
- Provide supplemental information and help to link metadata with elements of a program such as classes, variables, constructs, methods, etc.
- Are different from comments since they can affect how the program is treated by the compiler
class Flower {
public void displayInfo() {
System.out.println("I am a flower.");
class Rose extends Flower {
@Override
System.out.println("I am a rose.");
class Main {
public static void main(String[] args) {
Rose r1 = new Rose();
r1.displayInfo();
I am a rose
In the above example, both the superclass and subclass include the method displayInfo(). However, when the method is called, instead of the method of the superclass, the method of the subclass is called.
Annotations can be categorized broadly into 5 categories:
Category 1: Marker Annotations
The marker annotation is used to mark a declaration. It does not include any members or data. Only the presence of a marker annotation as an annotation is sufficient. An example of Marker Annotation is @Override
@TestAnnotation()
Category 2: Single value Annotations
A single value annotation consists of a single member only. This annotation allows a shorthand form to specify the value of the member. There is no need to specify the name of the member, only the value of the member has to be specified. There must, however, be a value for the name of the member in order to use this category of annotation.
@interface AnnotationName{
Int value();
int value() default 0;
To apply single value annotation, use
@AnnotationName(value=6)
Any value can be assigned.
Category 3: Full Annotations
Full Annotations include multiple data members, values, names, and pairs.
@TestAnnotation(owner= ”Ravi”, value= ”Class ”)
Category 4: Type Annotations
As the name suggests, Type Annotations are applied at any place where a type is being used. For instance, the return type of a method can be annotated. Type Annotations are declared with @Target Annotation
// Java Program to Demonstrate Type Annotation
// Importing required classes
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// Using target annotation to annotate a type
@Target(ElementType.TYPE_USE)
// Declaring a simple type annotation
@interface TypeAnnoExample{}
// Main class
public class GFG {
// Main driver method
public static void main(String[] args) {
// Annotating the type of a string
@TypeAnnoExample String string = "This is an example of type annotation";
System.out.println(string);
abc();
// Annotating return type of a function
static @TypeAnnoExample int abc() {
System.out.println("The return type of this function is annotated");
return 0;
This is an example of type annotation
The return type of this function is annotated
Become a Software Development Professional
Full stack java developer.
- Kickstart Full Stack Java Developer career with industry-aligned curriculum by experts
- Hands-on practice through 20+ projects, assessments, and tests
Full Stack Web Developer - MEAN Stack
- Comprehensive Blended Learning program
- 8X higher interaction in live online classes conducted by industry experts
Category 5: Repeating Annotations
It is possible to apply an annotation to a single item more than once using Repeating Annotations. @Repeatable annotation which is available in java.lang.annotation package is used to annotate the repeating annotations. The container type for the repeatable annotation is specified by the value field of this annotation. The container is specified as an annotation and its value field consists of an array of the repeatable annotation type. In order to use this type of annotation, the container annotation is created first and the annotation type is then specified as an argument to the @Repeatable annotation.
// Java Program to Demonstrate a Repeatable Annotation
import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
// Make Words annotation repeatable
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyRepeatedAnnoDemo.class)
@interface Words
String word() default "Welcome";
int value() default 0;
// Create container annotation
@interface MyRepeatedAnnoDemo
Words[] value();
public class Main {
// Repeat Words on newMethod
@Words(word = "This", value = 1)
@Words(word = "That", value = 2)
public static void newMethod()
Main obj = new Main();
try {
Class<?> c = obj.getClass();
// Obtain the annotation for newMethod
Method m = c.getMethod("newMethod");
// Display the repeated annotation
Annotation anno
= m.getAnnotation(MyRepeatedAnnoDemo.class);
System.out.println(anno);
catch (NoSuchMethodException e) {
System.out.println(e);
public static void main(String[] args) { newMethod(); }
@MyRepeatedAnnos(value={@Words(value=1, word="This"), @Words(value=2, word="That")})
Predefined/ Standard Annotations
As indicated in the hierarchy of annotations above, Java provides built-in or standard annotations. @Deprecated, @Override, and @SuppressWarnings are available in java.lang & @Retention, @Documented, @Target, and @Inherited are imported from java.lang.annotation package.
Annotation 1: @Deprecated
The @Deprecated annotation is used to indicate that the class, field, or method marked is no longer in use and has been replaced by a newer form. Whenever a class, field, or method marked with the @Deprecated annotation is used, the compiler gives a warning message that a deprecated class, field, or method is used. When an element has been deprecated, the Javadoc tag @deprecated tag must be used. There is a difference between the @deprecated tag and @Deprecated annotation. While the @deprecated tag is used for documentation, the @Deprecated annotation is used for runtime reflection.
public class DeprecatedDemo
@Deprecated
public void Display()
System.out.println("Deprecateddemo display()");
public static void main(String args[])
DeprecatedDemo d1 = new DeprecatedDemo();
d1.Display();
Deprecateddemo display()
Annotation 2: @Override
@Override is a marker annotation that can only be used on methods. A method that is annotated with @Override must override a method from the superclass. A compile-time error occurs if the method does not override the method from the superclass. This ensures that the superclass method is overridden and not overloaded. The code becomes more readable and maintenance issues can be avoided.
// Java Program to Illustrate Override Annotation
class ParentClass
public void Display()
System.out.println("Parent Class Display() Method");
}
public static void main(String args[])
ParentClass t1 = new ChildClass();
t1.Display();
// Extending above class
class ChildClass extends ParentClass
@Override
System.out.println("Child Class Display() Method");
Child Class Display() Method
Annotation 3: @SuppressWarnings
@SuppressWarnings is used to inform the compiler to suppress the specified compiler warnings. This is done by specifying the warnings to be suppressed by specific names. It can be applied to any type of declaration. There are two categories under which Java groups warnings - deprecated and unchecked. When a legacy code interfaces with a code that uses generics, an unchecked warning is generated.
// Java Program to illustrate SuppressWarnings Annotation
class DeprecatedDemo
public class SuppressWarningDemo
// If we comment below annotation, program generates
// warning
@SuppressWarnings({"checked", "deprecation"})
Annotation 4: @Documented
@Documented is a marker interface that specifies to a tool that a particular annotation has to be documented. Annotations are not included in the ‘Javadoc’ comments. By using @Documented annotation in the code, tools like Javadoc can process and include the annotated type in the generated document.
Annotation 5: @Target
@Target is used as an annotation to another annotation. The @Target annotation takes only one argument and this argument should be a constant value from the ElementType enumeration. The constants along with the corresponding declaration ars shown in the table below:
One or more values can be specified in a @Target annotation by using a braces-delimited list. For example, to specify an annotation that applies to fields and local variables, the following annotation can be used
@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE})
Annotation 6: @Inherited
@Inherited annotation is a marker annotation that is only used on annotation declaration. Only the annotations that are used on class declarations are affected by it. @Inherited causes the subclass to inherit the annotation from a superclass. Hence, when there is a request for a specific annotation to a subclass and it is not present in the subclass, the superclass is checked. If the annotation is present in the superclass and it is annotated with @Inherited, the annotation is returned.
Annotation 7: User-defined (Custom)
To annotate program elements, i.e. variables, constructors, methods, etc. user-defined annotations can be used. The user-defined annotations can be applied to the elements Ii.e. variables, constructors, classes, methods) just before their declaration.
Annotations are created by using @interface and are followed by the annotation name. An annotation can also have elements. They appear as methods but the implementation should not be provided for these elements. All the annotations extend java.lang.annotation.Annotation interface. The annotations cannot include the extended clause.
// Java Program to Demonstrate User-defined Annotations
package source;
import java.lang.annotation.Documented;
// User-defined annotation
@Documented
@ interface AnnotationDemo
String Developer() default "Ravi";
String Expirydate();
} // will be retained at runtime
// Driver class that uses @AnnotationDemo
public class Demo
@AnnotationDemo(Developer="Ravi", Expirydate="26-03-2020")
void fun1()
System.out.println("Demo method 1");
@AnnotationDemo(Developer="Kiran", Expirydate="26-03-2021")
void fun2()
System.out.println("Demo method 2");
System.out.println("Welcome");
Annotations are used for the following purposes:
- Instructions to the compiler: There are three types of built-in annotations @Deprecated, @Override, @SuppressWarnings that can be used to give instructions to the compiler, detect errors, and suppress warnings. For example, @Override annotation can be used to instruct the compiler to denote that the annotated method is overriding the method.
- Compile-time Instructions: Software build tools can generate code, XML files, and more by using the compile-time instructions that the annotations provide.
- Runtime Instructions: Annotations can also be defined to provide instructions to the program at runtime. These annotations can be accessed using Java Reflection.
Hope this article was able to give you a thorough understanding about annotations in Java. If you are looking to enhance your software development skills further, we would recommend you check Simplilearn’s Post Graduate Program in Full Stack Web Development . This course, designed in collaboration with Caltech CTME, can help you hone the required skills and make you job-ready in no time.
If you have any questions or doubts, feel free to post them in the comments below. Our team will review and get back to you with the solutions at the earliest.
Our Software Development Courses Duration And Fees
Software Development Course typically range from a few weeks to several months, with fees varying based on program and institution.
Get Free Certifications with free video courses
Software Development
Getting Started with Full Stack Java Development
Full-Stack Development 101: What is Full-Stack Development ?
Learn from Industry Experts with free Masterclasses
Java FullStack: Your Gateway to a Recession-Proof Future?
Learn to Develop a Full-Stack E-Commerce Site: Angular, Spring Boot & MySQL
Fuel Your 2024 FSD Career Success with Simplilearn's Masters program
Recommended Reads
Free eBook: Enterprise Architecture Salary Report
What Is Image Annotation and Why Is It Important in Machine Learning
What is Java: A Beginners Guide To Java
Free eBook: Pocket Guide to the Microsoft Certifications
TestNG Annotations in Selenium Webdriver
Java EE Tutorial: All You Need To Know About Java EE
Get Affiliated Certifications with Live Class programs
- PMP, PMI, PMBOK, CAPM, PgMP, PfMP, ACP, PBA, RMP, SP, and OPM3 are registered marks of the Project Management Institute, Inc.
- Prev Class
- Next Class
- No Frames
- All Classes
- Summary:
- Nested |
- Field |
- Constr |
- Detail:
Interface Annotation
- All Known Implementing Classes: Action , Addressing , BindingType , ConstructorProperties , Deprecated , DescriptorKey , Documented , FaultAction , FunctionalInterface , Generated , HandlerChain , Inherited , InitParam , MTOM , MXBean , Native , Oneway , Override , PostConstruct , PreDestroy , Repeatable , RequestWrapper , Resource , Resources , RespectBinding , ResponseWrapper , Retention , SafeVarargs , ServiceMode , SOAPBinding , SOAPMessageHandler , SOAPMessageHandlers , SupportedAnnotationTypes , SupportedOptions , SupportedSourceVersion , SuppressWarnings , Target , Transient , WebEndpoint , WebFault , WebMethod , WebParam , WebResult , WebService , WebServiceClient , WebServiceFeatureAnnotation , WebServiceProvider , WebServiceRef , WebServiceRefs , XmlAccessorOrder , XmlAccessorType , XmlAnyAttribute , XmlAnyElement , XmlAttachmentRef , XmlAttribute , XmlElement , XmlElementDecl , XmlElementRef , XmlElementRefs , XmlElements , XmlElementWrapper , XmlEnum , XmlEnumValue , XmlID , XmlIDREF , XmlInlineBinaryData , XmlJavaTypeAdapter , XmlJavaTypeAdapters , XmlList , XmlMimeType , XmlMixed , XmlNs , XmlRegistry , XmlRootElement , XmlSchema , XmlSchemaType , XmlSchemaTypes , XmlSeeAlso , XmlTransient , XmlType , XmlValue public interface Annotation The common interface extended by all annotation types. Note that an interface that manually extends this one does not define an annotation type. Also note that this interface does not itself define an annotation type. More information about annotation types can be found in section 9.6 of The Java™ Language Specification . The AnnotatedElement interface discusses compatibility concerns when evolving an annotation type from being non-repeatable to being repeatable. Since: 1.5
Method Summary
Method detail.
- Two corresponding array typed members x and y are considered equal if Arrays.equals(x, y) , for the appropriate overloading of Arrays.equals(long[], long[]) . Overrides: equals in class Object Parameters: obj - the reference object with which to compare. Returns: true if the specified object represents an annotation that is logically equivalent to this one, otherwise false See Also: Object.hashCode() , HashMap
- The hash code of an array member-value is computed by calling the appropriate overloading of Arrays.hashCode on the value. (There is one overloading for each primitive type, and one for object reference types.) Overrides: hashCode in class Object Returns: the hash code of this annotation See Also: Object.equals(java.lang.Object) , System.identityHashCode(java.lang.Object)
annotationType
Submit a bug or feature For further API reference and developer documentation, see Java SE Documentation . That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples. Copyright © 1993, 2024, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms . Also see the documentation redistribution policy .
Scripting on this page tracks web page traffic, but does not change the content in any way.
IMAGES
VIDEO
COMMENTS
Java Annotations. Java Annotation is a tag that represents the metadata i.e. attached with class, interface, methods or fields to indicate some additional information which can be used by java compiler and JVM. Annotations in Java are used to provide additional information, so it is an alternative option for XML and Java marker interfaces.
Category 5: Repeating Annotations These are the annotations that can be applied to a single item more than once. For an annotation to be repeatable it must be annotated with the @Repeatable annotation, which is defined in the java.lang.annotation package. Its value field specifies the container type for the repeatable annotation.The container is specified as an annotation whose value field is ...
The annotation type can be one of the types that are defined in the java.lang or java.lang.annotation packages of the Java SE API. In the previous examples, Override and SuppressWarnings are predefined Java annotations. It is also possible to define your own annotation type. The Author and Ebook annotations in the previous example are custom ...
Use of Annotations. Compiler instructions - Annotations can be used for giving instructions to the compiler, detect errors or suppress warnings. The built-in annotations @Deprecated, @Override, @SuppressWarnings are used for these purposes.; Compile-time instructions - Compile-time instructions provided by these annotations help the software build tools to generate code, XML files and many more.
Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate. Annotations have a number of uses, among them: Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings. Compile ...
Java annotation. 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 ...
Java annotations are one of the main ease-of-development features introduced in JDK 5. Annotations are like meta-tags that you can add to your code and apply to package declarations, type declarations, constructors, methods, fields, parameters and variables. ... An annotation type definition takes an "at" (@) sign, followed by the interface ...
A Java annotation is a small comment-like construct you can insert before class, method and field declarations. Annotations can be used to generate source code from, or be accessed at runtime via reflection. ... This signals to the Java compiler that this is a Java annotation definition. Notice that each element is defined similarly to a method ...
Annotations. Annotations have a number of uses, among them: Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings. Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth. Runtime processing — Some ...
Java annotations are a way to provide metadata about your code, which can be processed during compilation or runtime. They can be used to generate code, validate constraints, or modify the ...
1. Marker Annotations: The simplest kind of annotation, a marker annotation, contains no members and serves to mark a declaration. An example of this is @Override. 2. Single-Value Annotations: This type allows for a single value, which can be quite convenient when annotating with a single piece of information, like @SuppressWarnings(value ...
An annotation is a construct associated with Java source code elements such as classes, methods, and variables. Annotations provide information to a program at compile time or at runtime based on which the program can take further action. An annotation processor processes these annotations at compile time or runtime to provide functionality ...
1. By literal definition an annotation adds notes to an element. Likewise, Java annotations are tags that we insert into source code for providing more information about the code. Java annotations associate information with the annotated program element.
An annotation is a kind of metadata in Java that can be applied to various elements of Java source code so that later some tool, debugger, or application program can take advantage of these annotations; and help analyze the program in a positive and constructive way. Just to mention, we can annotate classes, methods, variables, parameters, and ...
Annotations in Java are a powerful tool that can be used to improve the quality of your code. They can be used to add information about the code, to specify dependencies, and to enforce rules. @Override: You can take advantage of this annotation to specify that a method of a child class has overridden a superclass method.
String comments(); Some important points about java annotations are: Annotation methods can't have parameters. Annotation methods return types are limited to primitives, String, Enums, Annotation or array of these. Java Annotation methods can have default values. Annotations can have meta annotations attached to them.
You can compare annotation definition to an interface definition. ... J2SE 5.0 provides four annotations in the java.lang.annotation package that are used only when writing annotations:
An annotation is a tag representing metadata about classes, interfaces, variables, methods, or fields. Annotations do not impact the execution of the code that they annotate. Some of the characteristics of annotations are: Begin with '@'. Do not alter the execution of the program.
Annotation types are a form of interface, which will be covered in a later lesson. For the moment, you do not need to understand interfaces. The body of the previous annotation definition contains annotation type element declarations, which look a lot like methods. Note that they can define optional default values.
2. What an Annotation Is. Simply put, annotations are Java types that are preceded by an "@" symbol. Java has had annotations ever since the 1.5 release. Since then, they've shaped the way we've designed our applications. Spring and Hibernate are great examples of frameworks that rely heavily on annotations to enable various design ...
Annotations works as a way to marking up the code. Several frameworks uses it, and some others make a great use of it producing your own. Besides, is important to understand that annotations are the equivalent to meta-data, but is much more than that, since it works as a tag language for the code.
The hash code of a string, enum, class, or annotation member-value I v is computed as by calling v.hashCode (). (In the case of annotation member values, this is a recursive definition.) The hash code of an array member-value is computed by calling the appropriate overloading of Arrays.hashCode on the value.
Class Level Annotation Example. The first step toward creating a custom annotation is to declare it using the @interface keyword: public @interface JsonSerializable {. } Copy. The next step is to add meta-annotations to specify the scope and the target of our custom annotation:
This is the definition of Implementation. import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * A marker annotation, forces the class which is to be defined as a data engine, to * extend {@code AbstractDataEngine} or any of its ...