像@Override这样的注释如何在Java内部工作?
任何人都可以向我解释注释如何在Java内部工作吗?
我知道我们如何通过在java中使用java.lang.annotation库来创建自定义注释。但我仍然不明白它在内部是如何工作的,例如,@Override注释。
如果有人能详细解释这一点,我将非常感激。
任何人都可以向我解释注释如何在Java内部工作吗?
我知道我们如何通过在java中使用java.lang.annotation库来创建自定义注释。但我仍然不明白它在内部是如何工作的,例如,@Override注释。
如果有人能详细解释这一点,我将非常感激。
各种注释之间的第一个主要区别是它们是在编译时使用,然后被丢弃(如)还是放置在已编译的类文件中并在运行时可用(如Spring的)。这由注释的@Retention策略确定。如果您正在编写自己的注释,则需要确定注释是在运行时(也许用于自动配置)还是仅在编译时(用于检查或代码生成)有用。@Override
@Component
使用批注编译代码时,编译器看到的注释就像它看到源元素上的其他修饰符一样,如访问修饰符 (/) 或 .当它遇到注释时,它会运行一个注释处理器,这就像一个插件类,它说它对特定注释感兴趣。注释处理器通常使用反射 API 来检查正在编译的元素,并且可能只是对它们运行检查、修改它们或生成要编译的新代码。 是第一个示例;它使用反射 API 来确保它可以在其中一个超类中找到方法签名的匹配项,如果不能,则使用 它来导致编译错误。public
private
final
@Override
Messager
有许多关于编写注释处理器的教程;这是一个有用的。查看处理器
接口上的方法,了解编译器如何调用注释处理器;main 操作在方法中发生,每次编译器看到具有匹配注释的元素时,都会调用该方法。process
除了其他人的建议之外,我建议您从头开始编写自定义注释及其处理器,以查看注释的工作原理。
例如,在我自己的注释中,我写了一个注释来检查方法在编译时是否重载。
首先,创建一个名为 的注释。此注释应用于方法,因此我用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 {
}
接下来,创建相应的处理器来处理由定义的注释注释的元素。对于 注释的方法,其签名必须出现多次。或者打印错误。@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 文件中后,使用并使用 javac.exe 创建一个类来编译它。@Overload
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()