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

Posted

技术标签:

【中文标题】Java 中如何以及在何处使用注解?【英文标题】:How and where are Annotations used in Java? 【发布时间】:2010-11-25 06:21:15 【问题描述】:

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

【问题讨论】:

cdb,我不确定你是否完全理解了赏金的概念——你在这里有很多很好的答案,但没有澄清他们缺少什么或你具体看什么因为,你增加了赏金。 (您在这里也这样做了:***.com/questions/1746550/…) 好吧,我知道这已经很老了,但是@delfuego:如果你要告诉 OP 他错误地使用了赏金,那么通过解释how to use them correctly 来跟进可能会有所帮助。 【参考方案1】:

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

class Foo 

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

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

class Foo 

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

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

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

它允许编译器警告您关于变量和 null 值的不当/未经检查的使用。

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

【讨论】:

【参考方案2】:

以下是一些可以使用注释的地方。

a. Annotations can be used by compiler to detect errors and suppress warnings
b. Software tools can use annotations to generate code, xml files, documentation etc., For example, Javadoc use annotations while generating java documentation for your class.
c. Runtime processing of the application can be possible via annotations.
d. You can use annotations to describe the constraints (Ex: @Null, @NotNull, @Max, @Min, @Email).
e. Annotations can be used to describe type of an element. Ex: @Entity, @Repository, @Service, @Controller, @RestController, @Resource etc.,
f. Annotation can be used to specify the behaviour. Ex: @Transactional, @Stateful
g. Annotation are used to specify how to process an element. Ex: @Column, @Embeddable, @EmbeddedId
h. Test frameworks like junit and testing use annotations to define test cases (@Test), define test suites (@Suite) etc.,
i. AOP (Aspect Oriented programming) use annotations (@Before, @After, @Around etc.,)
j. ORM tools like Hibernate, Eclipselink use annotations

您可以参考此link 了解有关注释的更多详细信息。

您可以参考此link 了解如何使用注释来构建简单的测试套件。

【讨论】:

【参考方案3】:

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

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

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

Google Guice - 例如@Inject 注释,当应用于构造函数时,Guice 运行时会根据定义的注入器查找每个参数的值。 @Inject 注释将很难使用 XML 配置文件进行复制,并且它与它所引用的构造函数的接近度非常有用(想象一下,必须搜索一个巨大的 XML 文件才能找到您设置的所有依赖注入)。

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

【讨论】:

【参考方案4】:

Where Annotations Can Be Used

注释可以应用于声明:类、字段、方法和其他程序元素的声明。在声明中使用时,按照惯例,每个注释通常都出现在自己的行中。

Java SE 8 更新:注解也可以应用于类型的使用。下面是一些例子:

类实例创建表达式:

新的@Interned MyObject();

类型转换:

myString = (@NonNull String) str;

实现子句:

类 UnmodifiableList 实现 @Readonly 列表 ...

抛出异常声明:

void monitorTemperature() 抛出 @Critical TemperatureException ...

【讨论】:

【参考方案5】:

Java 中的注解,提供了一种描述类、字段和方法的方法。本质上,它们是添加到 Java 源文件中的一种元数据形式,它们不能直接影响程序的语义。但是,可以使用反射在运行时读取注释,这个过程称为自省。然后它可以用来修改类、字段或方法。

库和 SDK(hibernate、JUnit、Spring 框架)经常利用此功能来简化或减少程序员在使用这些库或 SDK 时需要执行的代码量。因此,公平的做法是比如说注解和反射在 Java 中是齐头并进的。

我们还可以将注释的可用性限制为编译时或运行时。下面是创建自定义注释的简单示例

驱动程序.java

package io.hamzeen;

import java.lang.annotation.Annotation;

public class Driver 

    public static void main(String[] args) 
        Class<TestAlpha> obj = TestAlpha.class;
        if (obj.isAnnotationPresent(IssueInfo.class)) 

            Annotation annotation = obj.getAnnotation(IssueInfo.class);
            IssueInfo testerInfo = (IssueInfo) annotation;

            System.out.printf("%nType: %s", testerInfo.type());
            System.out.printf("%nReporter: %s", testerInfo.reporter());
            System.out.printf("%nCreated On: %s%n%n",
                    testerInfo.created());
        
    

TestAlpha.java

package io.hamzeen;

import io.hamzeen.IssueInfo;
import io.hamzeen.IssueInfo.Type;

@IssueInfo(type = Type.IMPROVEMENT, reporter = "Hamzeen. H.")
public class TestAlpha 


问题信息.java

package io.hamzeen;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author Hamzeen. H.
 * @created 10/01/2015
 * 
 * IssueInfo annotation definition
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface IssueInfo 

    public enum Type 
        BUG, IMPROVEMENT, FEATURE
    

    Type type() default Type.BUG;

    String reporter() default "Vimesh";

    String created() default "10/01/2015";

【讨论】:

【参考方案6】:

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

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

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

描述元素的约束或使用:例如@Deprecated, @Override,或@NotNull 描述元素的“性质”,例如@Entity, @TestCase, @WebService 描述一个元素的行为:@Statefull, @Transaction 描述如何处理元素:@Column, @XmlElement

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

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

注解的使用:

文档,例如XDoclet 编译 IDE 测试框架,例如JUnit IoC 容器,例如作为春天 序列化,例如XML 面向方面的编程 (AOP),例如Spring AOP 应用服务器,例如EJB 容器、Web 服务 对象关系映射 (ORM),例如休眠,JPA 还有更多...

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

【讨论】:

【参考方案7】:

它通过 (a) 编译器检查或 (b) 代码分析附加有关代码的附加信息

**

以下是内置注解:: 2 种

**

类型 1) 应用于 java 代码的注解:

@Override // gives error if signature is wrong while overriding.
Public boolean equals (Object Obj) 

@Deprecated // indicates the deprecated method
Public doSomething()....

@SuppressWarnings() // stops the warnings from printing while compiling.
SuppressWarnings("unchecked","fallthrough")

类型 2) 应用于其他注解的注解:

@Retention - Specifies how the marked annotation is stored—Whether in code only, compiled into the class, or available at run-time through reflection.

@Documented - Marks another annotation for inclusion in the documentation.

@Target - Marks another annotation to restrict what kind of java elements the annotation may be applied to

@Inherited - Marks another annotation to be inherited to subclasses of annotated class (by default annotations are not inherited to subclasses).

**

自定义注释::

** http://en.wikipedia.org/wiki/Java_annotation#Custom_annotations


为了更好地理解,请尝试以下链接:用示例详细说明


http://www.javabeat.net/2007/08/annotations-in-java-5-0/

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

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

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

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

归根结底,规则总是一样的:将随源而变的东西留在源内,将独立于源而变化的东西留在源外。

【讨论】:

【参考方案10】:

注解有2个视图

    用户视图,大多数时候,注释就像一个快捷方式,为你节省一些击键,或者让你的程序更具可读性

    供应商视图,处理器对注释的视图更多的是轻量级“接口”,您的程序确实遇到了一些问题,但没有明确“实现”特定接口(这里也称为注释)

    李>

例如在 jpa 中,您定义类似

@Entity class Foo ...

而不是

class Foo implements Entity ...

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

【讨论】:

【参考方案11】:

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

这里有几个资源:

Sun - The Java Persistence API Java EE 5 tutorial - JPA Introducing the Java EE 6 platform(检查所有三个页面)。

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

【讨论】:

【参考方案12】:

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

看看Hibernate Annotations

【讨论】:

虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。【参考方案13】:

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

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

【讨论】:

据说注解可以完全消除JSF的faces-config XML文件。在试图找出如何做到这一点时偶然发现了这篇文章......【参考方案14】:

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

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

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

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

【讨论】:

以上是关于Java 中如何以及在何处使用注解?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA - Annotation 注解 入门

Java注解知识点摘抄

Java注解教程:自定义注解示例,利用反射进行解析

Java注解详解以及如何实现自定义注解

Java注解教程及自定义注解

java注解基础入门