Java 中如何以及在哪里使用注解?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1372876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:17:44  来源:igfitidea点击:

How and where are Annotations used in Java?

javaannotations

提问by Biju CD

What are the major areas that we can use Annotations? Is the feature a replacement for XML based configuration?

我们可以使用注解的主要领域有哪些?该功能是否可以替代基于 XML 的配置?

采纳答案by ewernli

Annotations are meta-meta-objectswhich can be used to describe other meta-objects. Meta-objects are classes, fields and methods. Asking an object for its meta-object (e.g. anObj.getClass()) is called introspection. The introspection can go further and we can ask a meta-object what are its annotations (e.g. aClass.getAnnotations). Introspection and annotations belong to what is called reflectionand meta-programming.

注释是元元对象,可用于描述其他元对象。元对象是类、字段和方法。向一个对象询问它的​​元对象(例如anObj.getClass())被称为内省。自省可以更进一步,我们可以询问元对象它的注释是什么(例如aClass.getAnnotations)。自省和注释属于所谓的反射元编程

An annotation needs to be interpreted in one way or another to be useful. Annotations can be interpreted at development-timeby the IDE or the compiler, or at run-timeby a framework.

注释需要以一种或另一种方式解释才能有用。注释可以在开发时由 IDE 或编译器解释,或者在运行时由框架解释。

Annotation processing is a very powerful mechanism and can be used in a lot of different ways:

注释处理是一种非常强大的机制,可以以多种不同的方式使用:

  • to describe constraints or usage of an element: e.g. @Deprecated, @Override, or @NotNull
  • to describe the "nature" of an element, e.g. @Entity, @TestCase, @WebService
  • to describe the behavior of an element: @Statefull, @Transaction
  • to describe how to process the element: @Column, @XmlElement
  • 描述元素的约束或用法:例如@Deprecated, @Override,或@NotNull
  • 描述元素的“性质”,例如 @Entity, @TestCase, @WebService
  • 描述一个元素的行为: @Statefull, @Transaction
  • 描述如何处理元素: @Column, @XmlElement

In all cases, an annotation is used to describethe element and clarify its meaning.

在所有情况下,注释都用于描述元素并阐明其含义

Prior to JDK5, information that is now expressed with annotations needed to be stored somewhere else, and XML files were frequently used. But it is more convenient to use annotations because they will belong to the Java code itself, and are hence much easier to manipulate than XML.

在 JDK5 之前,现在用注解表示的信息需要存储在其他地方,并且经常使用 XML 文件。但是使用注释更方便,因为它们属于 Java 代码本身,因此比 XML 更容易操作。

Usage of annotations:

注释的使用:

  • Documentation, e.g. XDoclet
  • Compilation
  • IDE
  • Testing framework, e.g. JUnit
  • IoC container e.g. as Spring
  • Serialization, e.g. XML
  • Aspect-oriented programming (AOP), e.g. Spring AOP
  • Application servers, e.g. EJB container, Web Service
  • Object-relational mapping (ORM), e.g. Hibernate, JPA
  • and many more...
  • 文档,例如 XDoclet
  • 汇编
  • 集成开发环境
  • 测试框架,例如 JUnit
  • IoC 容器,例如 Spring
  • 序列化,例如 XML
  • 面向方面的编程(AOP),例如 Spring AOP
  • 应用服务器,例如 EJB 容器、Web 服务
  • 对象关系映射 (ORM),例如 Hibernate、JPA
  • 还有很多...

...have a look for instance at the project Lombok, which uses annotations to define how to generate equalsor hashCodemethods.

...看一下Lombok项目,它使用注释来定义如何生成equalshashCode方法。

回答by Dirk

There are mutiple applications for Java's annotations. First of all, they may used by the compiler (or compiler extensions). Consider for example the Overrideannotation:

Java的注解有多种应用。首先,它们可能被编译器(或编译器扩展)使用。以Override注释为例:

class Foo {

    @Override public boolean equals(Object other) {
        return ...;
    }
}

This one is actually built into the Java JDK. The compiler will signal an error, if some method is tagged with it, which does notoverride a method inherited from a base class. This annotation may be helpful in order to avoid the common mistake, where you actually intend to override a method, but fail to do so, because the signature given in your method does not match the signature of the method being overridden:

这实际上是内置在 Java JDK 中的。如果某些方法被标记为错误,编译器将发出错误信号,该方法不会覆盖从基类继承的方法。此注释可能有助于避免常见错误,即您实际上打算覆盖一个方法,但未能这样做,因为您的方法中给出的签名与被覆盖的方法的签名不匹配:

class Foo {

    @Override public boolean equals(Foo other) {  // Compiler signals an error for this one
        return ...;
    }
}

As of JDK7, annotations are allowed on any type. This feature can now be used for compiler annotations such as NotNull, like in:

从 JDK7 开始,任何类型都允许注解。此功能现在可用于编译器注释,例如NotNull,例如:

public void processSomething(@NotNull String text) {
    ...
}

which allows the compiler to warn you about improper/unchecked uses of variables and nullvalues.

这允许编译器警告您变量和值的不正确/未经检查的使用。

Another more advanced application for annotations involves reflection and annotation processing at run-time. This is (I think) what you had in mind when you speak of annotations as "replacement for XML based configuration". This is the kind of annotation processing used, for example, by various frameworks and JCP standards (persistence, dependency injection, you name it) in order to provide the necessary meta-data and configuration information.

另一个更高级的注释应用程序涉及运行时的反射和注释处理。当您将注释称为“基于 XML 的配置的替代品”时,这就是(我认为)您所想到的。这是一种注释处理,例如,由各种框架和 JCP 标准(持久性、依赖注入,等等)使用,以提供必要的元数据和配置信息。

回答by Chii

It is useful for annotating your classes, either at the method, class, or field level, something about that class that is not quite related to the class.

它对于在方法、类或字段级别注释您的类很有用,该类与该类不太相关。

You could have your own annotations, used to mark certain classes as test-use only. It could simply be for documentation purposes, or you could enforce it by filtering it out during your compile of a production release candidate.

您可以拥有自己的注释,用于将某些类标记为仅供测试使用。它可能只是用于文档目的,或者您可以通过在编译候选生产版本期间将其过滤掉来强制执行。

You could use annotations to store some meta data, like in a plugin framework, e.g., name of the plugin.

您可以使用注释来存储一些元数据,例如在插件框架中,例如插件的名称。

Its just another tool, its has many purposes.

它只是另一个工具,它有很多用途。

回答by Flaviu Cipcigan

Annotations are a form of metadata (data about data) added to a Java source file. They are largely used by frameworks to simplify the integration of client code. A couple of real world examples off the top of my head:

注释是添加到 Java 源文件的元数据(关于数据的数据)的一种形式。框架主要使用它们来简化客户端代码的集成。我脑海中浮现了几个真实世界的例子:

  • JUnit 4 - you add the @Testannotation to each test method you want the JUnit runner to run. There are also additional annotations to do with setting up testing (like @Beforeand @BeforeClass). All these are processed by the JUnit runner, which runs the tests accordingly. You could say it's an replacement for XML configuration, but annotations are sometimes more powerful (they can use reflection, for example) and also they are closer to the code they are referencing to (the @Testannotation is right before the test method, so the purpose of that method is clear - serves as documentation as well). XML configuration on the other hand can be more complex and can include much more data than annotations can.

  • Terracotta - uses both annotations and XML configuration files. For example, the @Rootannotation tells the Terracotta runtime that the annotated field is a root and its memory should be shared between VM instances. The XML configuration file is used to configure the server and tell it which classes to instrument.

  • Google Guice - an example would be the @Injectannotation, which when applied to a constructor makes the Guice runtime look for values for each parameter, based on the defined injectors. The @Injectannotation would be quite hard to replicate using XML configuration files, and its proximity to the constructor it references to is quite useful (imagine having to search to a huge XML file to find all the dependency injections you have set up).

  • JUnit 4 - 您将@Test注释添加到您希望 JUnit 运行程序运行的每个测试方法。还有其他注释与设置测试有关(如@Before@BeforeClass)。所有这些都由 JUnit runner 处理,它相应地运行测试。您可以说它是 XML 配置的替代品,但注释有时更强大(例如,它们可以使用反射)并且它们更接近于它们所引用的代码(@Test注释正好在测试方法之前,因此目的该方法的内容很清楚 - 也可用作文档)。另一方面,XML 配置可能更复杂,并且可以包含比注释更多的数据。

  • Terracotta - 使用注释和 XML 配置文件。例如,@Root注解告诉 Terracotta 运行时注解的字段是一个根,它的内存应该在 VM 实例之间共享。XML 配置文件用于配置服务器并告诉它要检测哪些类。

  • Google Guice - 一个例子是@Inject注解,当它应用于构造函数时,Guice 运行时会根据定义的注入器查找每个参数的值。该@Inject注释将是十分困难的使用XML配置文件进行复制,并且它靠近它引用到构造是非常有用的(想象一下,搜索到一个巨大的XML文件来找到所有你已经设置了依赖注入)。

Hopefully I've given you a flavour of how annotations are used in different frameworks.

希望我已经让您了解注释在不同框架中的使用方式。

回答by Michael Borgwardt

Is it a replacement for XML based configuration?

它是基于 XML 的配置的替代品吗?

Not completely, but confguration that corresponds closely to code structures (such as JPA mappings or dependency injection in Spring) can often be replaced with annotations, and is then usually much less verbose, annoying and painful. Pretty much all notable frameworks have made this switch, though the old XML configuration usually remains as an option.

不完全,但与代码结构(如 JPA 映射或 Spring 中的依赖注入)密切对应的配置通常可以用注解代替,这样通常就不那么冗长、烦人和痛苦了。几乎所有著名的框架都进行了这种转换,尽管旧的 XML 配置通常仍然是一个选项。

回答by Ken Liu

Java EE 5 favors the use of annotations over XML configuration. For example, in EJB3 the transaction attributes on an EJB method are specified using annotations. They even use annotations to mark POJOs as EJBs and to specify particular methods as lifecycle methods instead of requiring that implementation of an interface.

Java EE 5 倾向于使用注解而不是 XML 配置。例如,在 EJB3 中,EJB 方法上的事务属性是使用注释指定的。他们甚至使用注释将 POJO 标记为 EJB 并将特定方法指定为生命周期方法,而不是要求实现接口。

回答by medopal

Frameworks like Hibernate were lots of configuration/mapping is required uses Annotations heavily.

像 Hibernate 这样的框架需要大量的配置/映射,大量使用注解。

Take a look at Hibernate Annotations

看看Hibernate 注释

回答by BalusC

JPA (from Java EE 5) is an excellent example of the (over)use of annotations. Java EE 6 will also introduce annotations in lot of new areas, such as RESTful webservices and new annotations for under each the good old Servlet API.

JPA(来自 Java EE 5)是(过度)使用注释的一个很好的例子。Java EE 6 还将在许多新领域引入注解,例如 RESTful Web 服务和每个旧 Servlet API 下的新注解。

Here are several resources:

这里有几个资源:

It is not only the configuration specifics which are to / can be taken over by annotations, but they can also be used to control the behaviour. You see this good back in the Java EE 6's JAX-RS examples.

不仅可以通过注释接管配置细节,还可以使用它们来控制行为。您可以在 Java EE 6 的 JAX-RS 示例中看到这一点。

回答by Dapeng

There are 2 views of annotations

有 2 个注释视图

  1. user view, most of the time, annotations work like a shortcut, save you some key strokes, or make your program more readable

  2. vendor view, the processor's view of annotation is more of light weighted 'interface', your program DOES confront to SOMETHING but without explicitly "implements" the particular interface(here aka the annotation)

  1. 用户视图,大多数时候,注释就像一个快捷方式,可以为您节省一些按键,或者使您的程序更具可读性

  2. 供应商的观点,处理器的注释视图更像是轻量级的“接口”,您的程序确实会遇到某些事情,但没有明确“实现”特定的接口(这里又称为注释)

e.g. in jpa you define something like

例如在 jpa 中你定义了类似的东西

@Entity class Foo {...}

instead of

代替

class Foo implements Entity {...}

both speak the same thing "Foo is an Entity class"

两者都说同样的话“Foo 是一个实体类”

回答by Massimiliano Fliri

Annotations may be used as an alternative to external configuration files, but cannot be considered a complete replacement. You can find many examples where annotationi have been used to replace configuration files, like Hibernate, JPA, EJB 3 and almost all the technologies included in Java EE.

注释可以用作外部配置文件的替代品,但不能被视为完全替代品。您可以找到许多使用 annotationi 替换配置文件的示例,例如 Hibernate、JPA、EJB 3 以及 Java EE 中包含的几乎所有技术。

Anyway this is not always good choice. The purpose of using configuration files is usually to separate the code from the details of the environment where the application is running. In such situations, and mostly when the configuration is used to map the application to the structure of an external system, annotation are not a good replacement for configuration file, as they bring you to include the details of the external system inside the source code of your application. Here external files are to be considered the best choice, otherwise you'll need to modify the source code and to recompile every time you change a relevant detail in the execution environment.

无论如何,这并不总是好的选择。使用配置文件的目的通常是将代码与应用程序运行的环境细节分开。在这种情况下,主要是当配置用于将应用程序映射到外部系统的结构时,注解不是配置文件的良好替代,因为它们使您在源代码中包含外部系统的详细信息你的申请。这里外部文件被认为是最好的选择,否则你需要修改源代码并在每次更改执行环境中的相关细节时重新编译。

Annotations are much more suited to decorate the source code with extra information that instruct processing tools, both at compile time and at runtime, to handle classes and class structures in special way. @Overrideand JUnit's @Testare good examples of such a usage, already explained in detail in other answers.

注释更适合用额外信息装饰源代码,指示处理工具在编译时和运行时以特殊方式处理类和类结构。@Override和 JUnit@Test是这种用法的好例子,已经在其他答案中详细解释过。

In the end the rule is always the same: keep inside the source the things that change with the source, and keep outside the source the things that change independently from the source.

归根结底,规则总是一样的:随着源头变化的东西保持在源头内,而与源头无关地变化的东西保持在源头之外。