Java introduced annotations upon their Java 1.5 release. Since then, annotations have shaped the way we design our applications.
In this article, we’ll talk about a set of predefined annotation types in the Java SE API. Some annotation types are used by the Java compiler and some apply to other annotations.
What Is Annotation?
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 techniques.
Basically, an annotation assigns extra metadata to the source code it’s bound to. By adding an annotation to a method, interface, class, or field, we can:
- Inform the compiler about warnings and errors
- Manipulate source code at compilation time
- Modify or examine behavior at run-time
Read more about annotations at Core Java Tutorial for Beginners.
Java Built-in Annotations From java.lang Package
The predefined annotation types defined in java.lang are:
- @Deprecated — A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.
- @Override — Indicates that a method declaration is intended to override a method declaration in a supertype.
- @FunctionalInterface — An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification.
- @SafeVarargs — A programmer assertion that the body of the annotated method or constructor does not perform potentially unsafe operations on its varargs parameter.
- @SuppressWarnings — Indicates that the named compiler warnings should be suppressed in the annotated element (and in all program elements contained in the annotated element).
@Deprecated
The @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.
Example: The use of the @ 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.
// Javadoc comment follows
/**
* @deprecated
* explanation of why it was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
@Override
@Override annotation informs the compiler that the element is meant to override an element declared in a superclass.
Example:
package net.javaguides.annotations;
public class OverrideAnnotationExample {
public static void main(String[] args) {
BaseClass baseClass = new SubClass();
baseClass.test();
SubClass subClass = new SubClass();
subClass.test();
}
}class BaseClass {
public void test() {
System.out.println(“Inside baseclass”);
}
}class SubClass extends BaseClass {
@Override
public void test() {
System.out.println(“Inside subclass”);
}
}
Output:
Inside subclass
Inside subclass
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.
@FunctionalInterface
The @FunctionalInterface annotation indicates that an interface is a functional interface and contains exactly one abstract method.
Example: Let’s demonstrates the usage of @FunctionalInterface annotation with examples. Let’s create Sayable interface annotated with @FunctionalInterface annotation.
@FunctionalInterface
interface Sayable{
void say(String msg); // abstract method
}
Let’s demonstrate a custom functional interface via the main() method.
public class FunctionalInterfacesExample {
public static void main(String[] args) {
Sayable sayable = (msg) – > {
System.out.println(msg);
};
sayable.say(“Say something ..”);
}
}
@SafeVarargs
Java 7 introduced the @SafeVarargs annotation to suppress the unsafe operation warnings that arises when a method is having varargs (variable number of arguments).
Example:
package net.javaguides.annotations;
import java.util.ArrayList;
import java.util.List;public class SafeVarAnnotationExample {
@SafeVarargs
private void print(List…names) {
for (List < String > name: names) {
System.out.println(name);
}
}public static void main(String[] args) {
SafeVarAnnotationExample obj = new SafeVarAnnotationExample();
List < String > list = new ArrayList < String > ();
list.add(“Ramesh”);
list.add(“John”);
obj.print(list);
}
}
Output:
[Ramesh, John]
Java 9 extended the use of @SafeVarargs annotation so read more at Java @SafeVarargs Annotation.
@SuppressWarnings
@SuppressWarnings annotation indicates that the named compiler warnings should be suppressed in the annotated element (and in all program elements contained in the annotated element).
Example: Suppressing warnings on using unchecked generic types operations:
@SuppressWarnings(“unchecked”)
void uncheckedGenerics() {
List words = new ArrayList();
words.add(“hello”); // this causes unchecked warning
}
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
The @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
The @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
The @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.PACKAGE can be applied to a package declaration.
- ElementType.PARAMETER can be applied to the parameters of a method.
- ElementType.TYPE can be applied to any element of a class.
@Inherited
The @Inherited annotation indicates that the annotation type can be inherited from the superclass. (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
The @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.
Further Learning:
- Java @Deprecated Annotation
- Java @Override Annotation
- Java @FunctionalInterface Annotation
- Java @SafeVarargs Annotation
- Java @SuppressWarnings Annotation
- Core Java tutorials