Java中如何在哪里使用注释?


218

我们可以使用注释的主要领域是什么?该功能是否可以替代基于XML的配置?


2
cdb,我不确定您是否完全知道赏金的想法-您在这里有很多不错的答案,并且在没有澄清它们中缺少的内容或您具体寻找的内容时,您添加了赏金。(您在此处也这样做:stackoverflow.com/questions/1746550/…
delfuego,2009年

5
好的,我知道这太老了,但是@delfuego:如果您要告诉OP他使用了不正确的赏金,那么可能还会通过解释如何正确使用赏金来有所帮助。
流行

Answers:


308

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

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

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

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

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

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

注释的用法:

  • 文档,例如XDoclet
  • 汇编
  • 集成开发环境
  • 测试框架,例如JUnit
  • IoC容器,例如Spring
  • 序列化,例如XML
  • 面向方面的编程(AOP),例如Spring AOP
  • 应用程序服务器,例如EJB容器,Web服务
  • 对象关系映射(ORM),例如Hibernate,JPA
  • 还有很多...

...例如看一下Lombok项目,该项目使用批注定义了生成方法equalshashCode方法。


50

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) {
    ...
}

这样,编译器就可以警告您有关变量和值使用不当/未经检查的情况。

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


18

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

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

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

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

希望我给您带来了如何在不同框架中使用注释的信息。


12

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

库和SDK(hibernate,JUnit,Spring Framework)经常利用此功能来简化或减少程序员在不使用这些库或SDK的情况下将要执行的代码量。反射工作与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 {

}

IssueInfo.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

它可以替代基于XML的配置吗?

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


据说注释可以完全消除JSF的faces-config XML文件。跑遍这篇文章,同时尝试找出解决方法……
Brian Knoblauch 2010年

6

注释有2个视图

  1. 在大多数情况下,用户视图的注释都像快捷方式一样工作,为您节省了一些击键或使程序更具可读性

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

例如在jpa中,您定义类似

@Entity class Foo {...}

代替

class Foo implements Entity {...}

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


3

可以在哪里使用注释

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

Java SE 8 Update:注解也可以应用于类型的使用。这里有些例子:

  • 类实例创建表达式:

    新的@Interned MyObject();

  • 类型转换:

    myString =(@NonNull字符串)str;

  • 实现子句:

    类UnmodifiableList实现@Readonly List <@Readonly T> {...}

  • 引发异常声明:

    void monitorTemperature()引发@Critical TemperatureException {...}



2

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

以下是一些资源:

注解不仅可以/可以被注释所接管,而且还可以用来控制行为。您可以在Java EE 6的JAX-RS示例中看到这一点。


1

这对于在方法,​​类或字段级别上注释与该类不太相关的某些类很有用。

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

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

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


1

它通过(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 storedWhether 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/


0

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

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

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

最后,规则始终是相同的:将随源而变化的事物保持在源内,而将与源无关的变化事物保持在源外。


0

Java EE 5比XML配置更喜欢使用注释。例如,在EJB3中,使用注释指定EJB方法上的事务属性。他们甚至使用批注将POJO标记为EJB,并将特定方法指定为生命周期方法,而不需要该接口的实现。


0

Java注释的目的仅仅是将信息与带注释的程序元素相关联。Java批注可以在任何声明中用作修饰符,无论是包,类(包括枚举),接口(包括批注类型),字段,方法,形式参数,构造函数还是局部变量。

Java注释也可用于枚举常量。这样的注释被放置在它们注释的枚举常量之前。通常,Java批注会放在所有其他修饰符的前面,但这不是必需的。它们可以与其他改性剂自由混合。

详细阅读Java批注


0

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

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

您可以参考此链接以获取有关注释的更多详细信息。

您可以参考此链接,以了解如何使用批注构建简单的测试套件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.