Java 编译器如何处理注释?

Java 编译器如何处理注释?,java,annotations,Java,Annotations,我对java中注释的使用有一些疑问 如果注释不能转换为字节码,那么这些信息会去哪里? 元数据到哪里去了? Java反射如何使用这些信息 编译器如何处理注释 当我们说, @Override public void doSomething(){ } java编译器用它做什么 我知道它会检查方法签名,以便该方法应该是一个完全重写的方法,但是如何检查呢?有三种类型的注释请参见 @重写是一种特殊情况,因为编译器会执行附加检查。这一种很简单。编译器只需检查超类中具有相同名称和相同数量参数的方法,以及它们的

我对java中注释的使用有一些疑问

如果注释不能转换为字节码,那么这些信息会去哪里? 元数据到哪里去了? Java反射如何使用这些信息

编译器如何处理注释

当我们说,

@Override
public void doSomething(){
}
java编译器用它做什么


我知道它会检查方法签名,以便该方法应该是一个完全重写的方法,但是如何检查呢?

有三种类型的注释请参见


@重写是一种特殊情况,因为编译器会执行附加检查。

这一种很简单。编译器只需检查超类中具有相同名称和相同数量参数的方法,以及它们的顺序和类型。如果方法有
@Override
注释,但未找到该方法,则会生成错误

更有趣的问题是编译器如何处理在运行时具有平均值的注释。我假设它们是在字节码中添加的,但是在一些特殊的部分中包含了元信息。因此,在运行时jvm可以访问meta部分。作为证明,您始终可以对任何
对象调用
getAnnotations()

是源类型注释,用于检查特定方法是否遵循重写方法的约定,因此它在运行时不可用(因此在编译的字节码中逻辑上不存在)

我知道它会检查方法签名,以便该方法应该是一个完全重写的方法,但是如何检查


在读取源文件并将其转换为字节码的过程中,例如,根本不使用反射。有关其他编译器信息,请参阅。

编译注释(最终是常量数据)在类文件中存在,可以使用适当的方法getAnnotations()和friends进行访问。

注释(例如
@Override
实现为
public@interface@Override{}
具有,它可以允许将批注存储在类文件(
RetentionPolicy.class
RetentionPolicy.RUNTIME
)中,也可以将批注丢弃(
RetentionPolicy.SOURCE

@Override
方法的RetentionPolicy为
RetentionPolicy.SOURCE
,目标为
ElementType.method
(这意味着此方法只能在方法声明上注释)


PS如果您希望以反射方式读取注释,则必须将RetentionPolicy设置为
RetentionPolicy。RUNTIME

首先,有两种注释:运行时可访问(2种)和不可运行时访问。注释的行为由保留策略通过注释声明的注释来完成:-)。例如:

@Retention(RetentionPolicy.RUNTIME) // effectively visible to JVM Runtime
public @interface MethodInfo {
    String author() default "unspecified";
    String lastModification() default "unspecified"; // Format: yyyy-mm-dd
    ImplementationStatus implementationStatus();
}
JVM运行时可见注释可以在带注释的代码执行期间(或JVM加载时)通过反射进行访问。您可以将这些注释用作元数据持有者。元数据可以由其他代码处理,以执行各种操作,例如在执行给定方法之前检查带注释的方法实现状态

但是必须有人编写代码才能通过反射使用数据!最好的例子是应用服务器(AS),它根据需要从放置在某个特定目录中的JAR文件加载类。AS可以包含检查每个加载类是否有@Initialization注释注释的静态方法的代码,并立即执行这些方法。此注释类型由AS和为AS创建JAR和类的人定义,并在开发过程中使用它


运行时不可用的注释将在编译期间使用和计算@覆盖就是一个很好的例子。编译器插件可以使用自定义源代码注释,或者如果代码是由其他代码按需编译的,则可以使用自定义源代码注释。

请查看这是否有帮助,谢谢您的回复。请详细说明什么是“常量池”,以及在运行时如何使用它。这是类文件中存储常量数据的区域。您可能需要读取JVM引用。这实际上是错误的。注释存储在类文件的单独部分,而不是常量池中。请更正此问题或删除您的答案。是否可以查看编译器处理
@Override
注释的代码?@NikolayKuznetsov是的,请阅读OpenJDK中
javac
的源代码
@Retention(RetentionPolicy.RUNTIME) // effectively visible to JVM Runtime
public @interface MethodInfo {
    String author() default "unspecified";
    String lastModification() default "unspecified"; // Format: yyyy-mm-dd
    ImplementationStatus implementationStatus();
}