ChatGPT解决这个技术问题 Extra ChatGPT

How do annotations like @Override work internally in Java?

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.

What do you mean by "work internally"? The compiler? The runtime?
@chrylis Work internally means how it's automatic identified that this method is override method or this one is not override method. It's work on both time. like override annotation work in compile time and spring controller annotation is work in runtime

c
chrylis -cautiouslyoptimistic-

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.


it would be nice to point us at exactly how Spring's annotation processor parses the @Component and inject the class into its container
@shanyangqu That's off-topic for the question, which isn't Spring-specific. You can read the postprocessor classes yourself.
E
Eugene

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:

https://i.stack.imgur.com/fZ1W3.png


Above info is very good respect to JDK6(+1 for that), but how to achieve the same thing using JDK5 as well? Using JDK6 SupportedAnnotationTypes, AbstractProcessor class it became simpler but how the same thing happened in the past(like Spring FrameWork 2.5 on jdk5)?How JVM detect annotation processor like class in jdk5? can you please guide by editing the answer in 2 section(one for JDK5,Current Version Is For Jdk6+)?
In your class OverloadProcessor::process why it's entry.getValue() == 1? One don't have to add an annotation at the parent class/interface, so roundEnv.getElementsAnnotatedWith(Overload.class) won't get the parent class/interface, right?
I'm confused at this part but I think your answer is very helpful.
@s̮̦̩e̝͓c̮͔̞ṛ̖̖e̬̣̦t̸͉̥̳̼ If a method is treated as Overload, there should be at least another method with same name defined in the Class.
@Raining for a method to say Overloaded, it must appear more than once in the same class, but if it is ` == 1` then its an error.
M
Matt Ball

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.


I know that source code of Override annotation. But how it's work internally. like how it can be identified this method is not override method or this one is override method? or can i create my custom override annotation? and it should be works exactly same behavior like java override annotation
As I said in my answer, the behavior is not part of the annotation. The interpretation lies in the things which consume the annotation. Because of that, unless you change the consumer, you can't practically create your own custom version of @Override (or other standard annotations).
T
Thomas

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.


R
Ruchira Gayan Ranaweera

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.

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


@LuiggiMendoza java 1.7 annotation doc added
@Ruchira i was opened all links but still i am not cleared how it's work. Can u explain me in details like consider as spring annotations. I can do all the things by using annotation without write any configuration in spring.xml file. is it internally bind annotation to xml configuration?
@ChiragDasani take a look at this. this may help you static.springsource.org/spring/docs/3.0.0.M3/reference/html/… and also see this SO post stackoverflow.com/questions/2798181/…
K
Kusum

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!