How do annotations like @Override work internally in Java?

JavaAnnotations

Java Problem Overview


Can anybody explain to me how annotations work internally in java?

I know how we can create custom annotations by using java.lang.annotation library in java. But I still don't get how it's working internally for example, the @Override annotation.

I will be really thankful if anyone could explain that in detail.

Java Solutions


Solution 1 - Java

The first main distinction between kinds of annotation is whether they're used at compile time and then discarded (like @Override) or placed in the compiled class file and available at runtime (like Spring's @Component). This is determined by the @Retention policy of the annotation. If you're writing your own annotation, you'd need to decide whether the annotation is helpful at runtime (for autoconfiguration, perhaps) or only at compile time (for checking or code generation).

When compiling code with annotations, the compiler sees the annotation just like it sees other modifiers on source elements, like access modifiers (public/private) or final. When it encounters an annotation, it runs an annotation processor, which is like a plug-in class that says it's interested a specific annotation. The annotation processor generally uses the Reflection API to inspect the elements being compiled and may simply run checks on them, modify them, or generate new code to be compiled. @Override is an example of the first; it uses the Reflection API to make sure it can find a match for the method signature in one of the superclasses and uses the Messager to cause a compile error if it can't.

There are a number of tutorials available on writing annotation processors; here's a useful one. Look through the methods on the Processor interface for how the compiler invokes an annotation processor; the main operation takes place in the process method, which gets called every time the compiler sees an element that has a matching annotation.

Solution 2 - Java

Besides what others suggested, I recommend you write a customized annotation and its processor from scratch to see how annotation works.

In my own, for example, I have written an annotation to check whether methods are overloaded in compile time.

Firstly, create an annotation named Overload. This annotation is applied to method so I annotate it with @Target(value=ElementType.METHOD)

package gearon.customAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(value=ElementType.METHOD)
public @interface Overload {
    
}

Next, create corresponding processor to handle elements annotated by defined annotation. For method annotated by @Overload, its signature must appear more than one time. Or the error is printed.

package gearon.customAnnotation;

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;

@SupportedAnnotationTypes("gearon.customAnnotation.Overload")

public class OverloadProcessor extends AbstractProcessor{

	@Override
	public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
		// TODO Auto-generated method stub
		HashMap<String, Integer> map = new HashMap<String, Integer>();
		
		for(Element element : roundEnv.getElementsAnnotatedWith(Overload.class)){
			String signature = element.getSimpleName().toString();
			int count = map.containsKey(signature) ? map.get(signature) : 0;
			map.put(signature, ++count);
		}
		
		for(Entry<String, Integer> entry: map.entrySet()){
			if(entry.getValue() == 1){
				processingEnv.getMessager().printMessage(Kind.ERROR, "The method which signature is " + entry.getKey() +  " has not been overloaded");
			}
		}
		return true;
	}
}

After packaging annotation and its process into a jar file, create a class with @Overload and use javac.exe to compile it.

import gearon.customAnnotation.Overload;

public class OverloadTest {
	@Overload
	public static void foo(){
	}
	
	@Overload
	public static void foo(String s){
		
	}
	
	@Overload
	public static void nonOverloadedMethod(){
		
	}
} 

Since nonOverloadedMethod() has not actually been overloaded, we will get the output like below:

enter image description here

Solution 3 - Java

Here's @Override: http://www.docjar.com/html/api/java/lang/Override.java.html.

There's nothing special about it that differentiates it from an annotation you might write yourself. The interesting bits are in the consumers of the annotations. For an annotation like @Override, that would be in the Java compiler itself, or a static code analysis tool, or your IDE.

Solution 4 - Java

Follow this link. This will provide close answer for your problem. If we focused on annotations in Java, Annotations were introduced in Java 5 and are not Spring specific. In general, annotations allow you to add metadata to a class, method or variable. An annotation can be interpreted by the compiler (for example, the @Override annotation) or by a framework such as spring (for example, the @Component annotation).

In addition I am adding more references.

  1. http://www.codeproject.com/Articles/272736/Understanding-Annotations-in-Java
  2. http://docs.oracle.com/javase/7/docs/api/java/lang/annotation/package-summary.html
  3. http://www.coderanch.com/how-to/java/AnnotationsExample

Solution 5 - Java

Basically, annotations are just markers which are read by the compiler or the application. Depending on their retention policy they are available at compile time only or are readable at runtime using reflection.

Many frameworks use runtime retention, i.e. they reflectively check whether some annotations are present on a class, method, field etc. and do something if the annotation is present (or not). Additionally, members of annotations can be used to pass further information.

Solution 6 - Java

Even I was looking for the answer of the same question. the below link provided the consolidated good stuff to get the inside of annotations. https://dzone.com/articles/how-annotations-work-java Hope it helps!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChirag DasaniView Question on Stackoverflow
Solution 1 - Javachrylis -cautiouslyoptimistic-View Answer on Stackoverflow
Solution 2 - JavaEugeneView Answer on Stackoverflow
Solution 3 - JavaMatt BallView Answer on Stackoverflow
Solution 4 - JavaRuchira Gayan RanaweeraView Answer on Stackoverflow
Solution 5 - JavaThomasView Answer on Stackoverflow
Solution 6 - JavaKusumView Answer on Stackoverflow