Java中注解的目的是什么?

7

我理解注释的作用在于可以修改代码,而不是作为代码本身,例如:

@Author(
   name = "Benjamin Franklin",
   date = "3/27/2003"
)

但我不明白使用注释比只说name = "Benjamin Franklin"更好/更清晰/更简洁的原因在哪里?添加注释如何加强代码?

编辑:抱歉再问一个问题,我知道@ Override可以帮助防止/跟踪调用方法或类时的拼写错误,但它是如何做到的?它是否对实际程序有所帮助?


编译器使用覆盖注释来确保您实际编写的是您所想的内容。 - Dave Newton
5个回答

6

注释只是元数据,本身没有太大用途。必须有一个注释处理器,在编译器或运行时级别使用它们来完成某些任务。

例如,使用以下注释:

@Author(
   name = "Benjamin Franklin",
   date = "3/27/2003"
)

例如,一些注解处理器可能会在运行时使用反射读取它,并创建一些日志文件,记录此作者在该日期上所注释的内容。

3

注解是元数据。

@Override 注解用于确保您覆盖了超类的方法而不仅仅是使用相同名称的方法。常见错误包括:

  • 拼写方法名错误 equal(Object o) 而不是 equals(Object o)
  • 放置不同的参数集合

    MyString 扩展 String { public boolean equals(MyString str) {} }

equals(MyString str) 不会覆盖方法 equals(Object o),因此将不会被标准 Java 比较器 (例如 List.contains() 等一些标准函数) 使用,这容易发生错误情况。该注解帮助编译器确保您正确编写所有内容,并以此帮助程序。

@Deprecated 注解不会使程序无法编译,但它会让开发人员考虑使用可能会在未来版本中删除的代码。因此,他们(开发人员)会考虑转移到另一组(更新的)函数。如果您使用标志 -Xlint 编译程序,则编译过程将返回错误,除非您删除所有已弃用的代码或明确标记它们为注解 @SuppressWarnings("deprecation")

@SuppressWarnings 用于抑制警告(是的,我知道这是显而易见的 :))。有一种使用 @SuppressWarnings("deprecation") 的弃用抑制,使用 @SuppressWarnings("unchecked") 的不安全类型转换以及其他一些。当您的项目编译器具有编译标志 -Xlint 时,这对于您无法(或不想)更改的情况非常有用。

还有一些注解处理器可以集成到程序构建过程中,以确保程序代码符合某些标准。例如,使用 IntelliJ Idea IDE 注解处理器,您可以使用 @Nullable@NotNull 注解。它们向其他程序员显示他们在使用您的代码时,可以将 null 作为某个参数传递给方法还是不传递。如果他们传递 null,则会在编译期间或执行单行方法代码之前引发异常。

因此,如果您充分利用它们,注解非常有用。


可选注释(Optional Annotations)如 @FunctionalInterface@SuppressWarnings("unchecked") 与系统实际考虑并更新其标志的区别在哪里?我认为注释用于告诉用户这是什么,例如 @Entity@Consumer@Configuration 等等。系统不关心这些名称,对吗?这些有一个术语吗? - raja777m
所有这些都可以使用正常的语言特性完成。实际上,Java许多现有的功能都可以被视为注解。比如在类/方法前面写“public”。...倒不如直接说public static deprecated nowarn myMethod() …注解似乎只是一个特性的复制,因为设计师忘记他们已经拥有了这个东西。…如果我漏掉了什么,请纠正我... - anon

1

注解最有可能被其他程序使用。例如:

@Override IDE(编译器?)确保签名匹配

@Deprecated IDE标记出现,编译器警告

@FXML JavaFX可以使用这些注解在控制器类中初始化变量,当一个.fxml文件被膨胀时(参见http://docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm)。它们也被JavaFX Scene Builder使用。


1

注解作为标记代码的一种方式。多个框架使用它,有些还可以用于生成自己的框架。

此外,重要的是要理解注解相当于元数据,但它不仅如此,因为它可以作为代码的标签语言。


0

Java @注解

@注解(自Java 5起)添加了元数据,用于编译、部署和运行时的指令。它由RetentionPolicy定义。

RetentionPolicy定义了生命周期

  • RetentionPolicy.SOURCE:它只在编译时可见(@Override, @SuppressWarnings, @StringDef)。例如,它可以被apt用来生成一些代码
  • RetentionPolicy.CLASS:它在编译和部署时可见(.class)。例如,它可以被ASM或Java AOP范例如AspectJ使用
  • RetentionPolicy.RUNTIME:它在部署和运行时可见。例如,它可以被使用java reflection的getAnnotations()方法。 Dagger 2使用@Scope注解

创建自定义注解

@Retention(<retention_policy>) //optional
@Target(<element_type>) //optional to specify Java element like, field, method...
@Inherited // optional will be visible by subclass 
@Documented // optional will be visible by JavaDoc
@interface MyAnnotation {
    //attributes:
    String someName();
}

使用

@MyAnnotation(someName = "Alex")
public class SomeClass {
}

这并没有涉及到被问的问题。你只是描述了它是什么。楼主问的是,为什么会这样。 - anon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接