Annotations in Java
Tags: java, computerscience, programming
Published: 2021-02-25 14:21:37

**What are Annotations?**
Annotations provide auxiliary information about the program. It can be attached with classes, interfaces, methods, constructors to provide additional information which is helpful to JVM and java compilers. It does not affect the execution of the code. It was firstly implemented in Java 5. They are started with ‘@’. 

Java Annotations are categorised into:
- **Built-in Annotations**

*Java provides some built-in annotations imported from java.lang:*

1) `@Override:`

```
class Shape{  
    void findArea(){
        System.out.println("finding area");
    }  
}  
      
    class Square extends Shape{  
        @Override  
        void findArea(){
            System.out.println("finding area of a square");
            
        }
    }  
      
    class Main{  
        public static void main(String args[]){  
        Shape sh = new Square();  
        sh.findArea();  
    }
}  
```

Output:
```
finding area of a square
```

2) `@SuppressWarnings:`

This annotation is used to stop the compiler from showing warnings. These are of two categories: deprecation and unchecked.

Here is the demo:

```
import java.util.*;  
class Main{  
    @SuppressWarnings("unchecked")  
    public static void main(String args[]){  
        ArrayList arr=new ArrayList();  
        arr.add("abc");  
        arr.add("def");  
        arr.add("ghi");  
          
        for(Object obj:arr)  
        System.out.println(obj);  
    }
}  
```
If we remove the SuppressWarnings annotation then the compiler will generate a warning stating that “Main.java uses unchecked or unsafe operations” because we didn’t specify the type of ArrayList as they are generic in nature.

3) `@Deprecated:`
This annotation states that the marked element can no longer be used. If the element is used, then the compiler will generate a warning for the same. It is used to give a message that the deprecated methods may no longer be used in future versions. 

Here is the demo:

```
class Base{  
    void non_deprecated(){
        System.out.println("hello m");
    }   
    @Deprecated  
    void deprecated(){
        System.out.println("hello n");
    }  
}   
class Main{  
    public static void main(String args[]){  
    Base obj = new Base();  
    obj.deprecated();  
    }
}  
```

Output: 
```
Main.java uses or overrides a deprecated API.
```

Before proceeding towards other built-in annotations, let’s take a look at what are custom annotations.

It also provides four built-in annotations from java.lang.annotations, these built-in annotations are used in custom annotations also known as Meta Annotations.

1) `@Retention:`

It specifies how long the annotation will be in use. It has following options:

`RetentionPolicy.CLASS` : retained by the compiler and ignored by the JVM.
`RetentionPolicy.SOURCE` : retained at source level and ignored by the compiler
`RetentionPolicy.RUNTIME` : retained by the JVM and used at the runtime 
Environment.

(RetentionPolicy is the parameter of `@Retention` annotation.)

2) `@Documented:`

It specifies that the marked element needs to be documented by JavaDoc. 
For example:
```
import java.lang.annotation.*;

@Documented
@interface Example {

   // Annotation element definitions
   
}
```

It will make the information appear in @Example to JavaDocs.

3) `@Target:`
It indicates where the annotation is to be used. For eg. if the type is specified as TYPE then the annotation is to be used in class or interface. 

There are following target values for the annotation:

ElementType.METHOD for methods
ElementType.PACKAGE for packages
ElementType.PARAMETER for parameters
ElementType.TYPE for class, interfaces
ElementType.ANNOTATION_TYPE for annotation type
ElementType.CONSTRUCTOR for constructors
ElementType.LOCAL_VARIABLE for local variables
ElementType.FIELD for fields

Code: 
```
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})  
@interface AnnotationExample{  
    int value_1();  
    String value_2();  
}  
```
The above code specifies the annotation for class, fields and methods.

4) `@Inherited:`
It specifies that the marked element can be inherited from the superclass.

Code: 

```
java.lang.annotation.Inherited

@Inherited
public @interface AnnotationExample {

}
@AnnotationExample
public class Base { 
  //Base class body
}
public class Child extends Base { 
   //Child class body
}
```
Here the class Base is using annotation @AnnotationExample which is marked with @inherited annotation. It means the sub-class Child inherits the @AnnotationExample.

Some annotations were introduced in Java 9, here is the list below:
1)`@Repeatable:`It came in Java SE 8 and signifies that the marked annotation can be used more than once to the same declaration or type use.

Let’s suppose you want an annotation to be repeated like in the below example:
```
@interface Month {
  String name();
}
@Month(name = "january")
@Month(name = "march")
@Month(name = "june")
@Month(name = "october")//@Month annotation repeated 4 times
class Birthday {
}
```
Till Java 7 this kind of program used to produce an error but from Java 8 the concept of repeating annotation got accepted but there is a certain way to achieve it. 

Let’s see how:

```
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
 @Repeatable(Months.class)
 @interface Month {
   String name();
 }
 @Retention(RetentionPolicy.RUNTIME)
 @interface Months {
   Month[] value();
 }
 @Month(name = "january") @Month(name = "march") @Month(name = "june") @Month(name = "october")
 class Birthday {
 }
```
Here, Months is the Container Annotation.
 
To use the above annotations, do as follows:
```
public class RepeatingAnnotations {
  public static void main(String args[]) {
   Month[] monthArray = Birthday.class.getAnnotationsByType(Month.class);
   for (Month month : monthArray) {
    System.out.println(month.name());
   }
  }
 }
```

Output:
```
january
march
june
october
```
2) `@SafeVarargs:`
This annotation was introduced in Java 7 and additional features came upto Java 9. It can be used with final methods, constructors, static methods and private instance methods. This annotation makes sure that the method does not perform any unsafe operations on its varargs parameters. One important thing about this annotation is that it cannot be applied to overridden methods but can be applied otherwise.

3) `@FunctionalInterface:`
This annotation was introduced in Java 8. It allows only one abstract method inside them, due to this feature, they are also known as Single Abstract Method interfaces (SAM interfaces). If this rule is violated, the compiler will generate an error.

Let’s see an example:

```
@FunctionalInterface
interface Rectangle 
{ 
    int calc_area(int x, int y); 
} 
  
class Main 
{ 
    public static void main(String args[]) 
    { 
        int a = 5; 
        int b = 6;
        
  
        // lambda expression to define the calculate method 
        Rectangle r = (int x, int y)->x*y; 
  
        // parameter passed and return type must be 
        // same as defined in the prototype 
        int result = r.calc_area(a,b); 
        System.out.println(result); 
    } 
} 
 ```
Output:
```
30
```

***Custom Annotations***

You can create custom annotations using `@interface` along with the name of the annotation. These annotations can have elements but should not have the implementation of these elements.
`@Documented`, `@Inherited`, `@Target`, `@Retention` are some of the annotations that are used with the custom annotations.

Here is an example:
```
import java.util.ArrayList;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;



@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)

@interface CustomAnnotation{
    String name();
    int emp_id();
}

@CustomAnnotation(name="John",emp_id=101)
class Employee{
    String dept_name;
    int dept_id;
    
    public Employee(String dept_name, int dept_id){
        super();
        this.dept_name = dept_name;
        this.dept_id = dept_id;
    }
}

public class Main{
    public static void main(String[] args){
        Employee obj = new Employee("IT", 111);
        
        Class c = obj.getClass();
        Annotation an = c.getAnnotation(CustomAnnotation.class);
        CustomAnnotation ca = (CustomAnnotation)an;
        System.out.println(ca.name());
        
    }
}
```

**What are the Types of Java Annotations?**

These are the types of annotations:
1) **Marker Annotations:** Annotations having no methods are marker annotations, for eg: @Override and @Deprecated.
```
@interface AnnotationExample { }
```

2) ***Single-valued annotations:*** Annotation having one method are single-valued annotations, here is an example:
```
@interface AnnotationExample {
	int item();
}
```
If you want to provide a default value, then,
```
@interface AnnotationExample {
	int item() default 100;
}
```

3) ***Multi-valued annotations:*** Annotations having more than one method are multi-valued annotations, 

here is an example:
```
@interface AnnotationExample {
	int item1();
	int item2();
	String item3();
}
```
```
@interface AnnotationExample {
	int item1() default 1;
	int item2() default “abc”;
	String item3() default “Hello”;
}
```
***Commonly Asked Interview Questions on Java Annotation***

Annotations in Java has been one of the important concepts to help prepare for any Java interview. Here's a detailed [interview questions](https://www.interviewbit.com/java-interview-questions/) guide that will help you in your Java Interview preparation.

**1. What are meta-annotations in java, list some of them?**

Meta-Annotations are annotations that are applied to other annotations. Below is the list of meta-annotations in Java:
@Documented
@Retention
@Inherited
@Target

**2. What is the parent class of the Annotation class?**

Object
	
**3. What is the package name for Annotation class?**
	
Java.text

**4. Why are annotations used?**
     
They are used to give certain instructions to the compiler.

**5. What are the typical use cases of Annotations?**

Information for the compiler – with annotations, the compiler can detect errors or suppress warnings.

Compile-time and deployment-time processing – software tools can process annotations and generate code, configuration files, etc.
Runtime processing – annotations can be examined at runtime to customize the behavior of a program.
    
**6. What object types can be returned from a method annotation declaration?**

The return type must be a primitive, String, Class, Enum, or an array of one of the previous types. Otherwise, the compiler will throw an error.
 
**7. Is it possible to extend annotations?**

No. Annotations always extend java.lang.annotation.Annotation, as stated in the Java Language Specification.
If we try to use the extends clause in an annotation declaration, we'll get a compilation error.

**8. Name 5 pre-defined annotations in Java.**
`@SuppressWarnings`
`@Deprecated`
`@Override`
`@SafeVarargs`
`@FuntionalInterface`