注释如何在内部工作

有人可以解释我怎么注释在java内部工作?

我知道我们如何通过在java中使用java.lang.annotation库来创build自定义注释。 但是我仍然没有足够的想法如何在@Override注释内部工作。

我真的很感激,如果有人详细解释它。

各种注释之间的第一个主要区别是它们是在编译时使用,然后被丢弃(如@Override )还是放在编译后的类文件中,并在运行时可用(如Spring的@Component )。 这由注解的@Retention策略决定。 如果您正在编写自己的注释,则需要确定注释在运行时(可能是自动configuration)还是仅在编译时(用于检查或代码生成)是否有用。

编译带有注释的代码时,编译器会看到注释,就像它看到源元素上的其他修饰符一样,如访问修饰符( public / private )或final 。 当它遇到一个注释时,它会运行一个注释处理器,就像插件类一样,它说它对一个特定的注释感兴趣。 注释处理器通常使用Reflection API来检查正在编译的元素,并且可以简单地对它们执行检查,修改它们或生成要编译的新代码。 @Override是第一个例子; 它使用Reflection API来确保它可以在其中一个超类中find方法签名的匹配,并使用Messager在不能的情况下导致编译错误。

编写注释处理器有许多教程。 这是一个有用的 。 通过Processor接口上的方法查看编译器如何调用注释处理器; 主要的操作发生在process方法中,每当编译器看到一个具有匹配注释的元素时就会调用它。

除了别人的build议之外,我build议你从头开始编写一个定制的注释和处理器,看看注释是如何工作的。

例如,我自己写了一个注释来检查方法是否在编译时被重载。

首先,创build一个名为Overload的注释。 这个注解被应用于方法,所以我用@Target(value=ElementType.METHOD)

 package gearon.customAnnotation; import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target(value=ElementType.METHOD) public @interface Overload { } 

接下来,创build相应的处理器来处理由定义的注释注释的元素。 对于由@Overload注释的方法,其签名必须出现多次。 或者打印错误。

 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; } } 

在将注解及其过程打包成jar文件后,使用@Overload创build一个类并使用javac.exe进行编译。

 import gearon.customAnnotation.Overload; public class OverloadTest { @Overload public static void foo(){ } @Overload public static void foo(String s){ } @Overload public static void nonOverloadedMethod(){ } } 

由于nonOverloadedMethod()实际上没有被重载,我们将得到如下的输出:

在这里输入图像说明

这里是@Override : http : //www.docjar.com/html/api/java/lang/Override.java.html 。

没有什么特别的地方可以把它和你自己写的注释区分开来。 有趣的部分在注释的消费者中。 对于像@Override这样的注释,可以在Java编译器本身,静态代码分析工具或IDE中使用。

按照这个链接 。 这将为您的问题提供密切的答案。 如果我们专注于Java中的注释,注释是在Java 5中引入的,而不是Spring特定的。 通常,注释允许您将元数据添加到类,方法或variables。 注释可以被编译器解释(例如,@Override注释)或者像Spring这样的框架(例如@Component注解)。

另外我join了更多的参考资料。

  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

基本上,注释只是由编译器或应用程序读取的标记。 根据其保留策略,它们仅在编译时可用,或者在运行时使用reflection可读。

许多框架使用运行时保留,也就是reflection地检查某些注释是否出现在类,方法,字段等,如果注释存在(或不存在),则执行某些操作。 另外,注释的成员可以用来传递更多的信息。