Java中使用注释的方式和位置?

我们可以使用注释的主要方面是什么? 该function是否替代基于XML的configuration?

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

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

注释处理是一个非常强大的机制,可用于很多不同的方式:

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

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

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

注释的用法:

  • 文档,例如XDoclet
  • 汇编
  • IDE
  • testing框架,例如JUnit
  • IoC容器,如Spring
  • 序列化,例如XML
  • 面向方面的编程(AOP),例如Spring AOP
  • 应用程序服务器,例如EJB容器,Web服务
  • 对象关系映射(ORM),例如Hibernate,JPA
  • 还有很多…

…在Lombok项目中查看实例,该项目使用注释来定义如何生成equalshashCode方法。

有很多Java注释的应用程序。 首先,它们可能被编译器(或编译器扩展)使用。 考虑例如覆盖注释:

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

这个实际上是内置到Java JDK中的。 编译器会发出一个错误信息,如果某个方法被标记了,那么它不会覆盖从基类inheritance的方法。 为了避免常见的错误,这个注释可能会有帮助,因为您的方法中的签名与被覆盖的方法的签名不匹配:

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

即将到来的JDK7将允许任何types的注释。 已经有提议将这个特性用于编译器注释,如NotNull ,如下所示:

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

这可能会允许编译器警告您有关variables和值的不当使用/未经检查的使用。

另一个更高级的注释应用程序在运行时涉及reflection和注释处理。 这是(我认为)当您将注释称为“replace基于XML的configuration”时,您想到的是什么。 这是一种使用的注释处理,例如,通过各种框架和JCP标准(持久性,dependency injection,你的名字)来提供必要的元数据和configuration信息。

注释是添加到Java源文件的元数据(关于数据的数据)的一种forms。 它们主要被框架用来简化客户端代码的集成。 我的头顶几个现实世界的例子:

  • JUnit 4 – 将@Test注释添加到您希望JUnit运行器运行的每个testing方法。 还有一些额外的注释来设置testing(如@Before@BeforeClass )。 所有这些都由JUnit运行器进行处理,该运行器相应地运行testing。 你可以说这是对XMLconfiguration的替代,但是注释有时更强大(例如,它们可以使用reflection),而且它们更接近它们所引用的代码( @Text注释@Text在testing方法之前,所以该方法的目的是明确的 – 作为文件也是如此)。 另一方面,XMLconfiguration可能更复杂,并且可能包含比注释更多的数据。

  • 兵马俑 – 使用注释和XMLconfiguration文件。 例如, @Root批注告诉Terracotta运行时注释的字段是一个根,它的内存应该在VM实例之间共享。 XMLconfiguration文件用于configuration服务器并告诉它要testing哪些类。

  • Google Guice – 一个例子就是@Inject注解,当它应用于构造函数时,Guice运行时会根据定义的注入器查找每个参数的值。 使用XMLconfiguration文件复制@Inject注解将非常困难,并且它接近它所引用的构造函数是相当有用的(假设必须search一个巨大的XML文件来查找所有dependency injection)。

希望我已经给了你如何在不同的框架中使用注释的味道。

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

这个特性经常被库和SDK(hibernate,JUnit,Spring Framework)利用来简化或者减less程序员的代码量,除非在这个库或者SDK中使用这个库。所以,说Annotations和反思在Java中携手合作。

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

Driver.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"; } 

它是基于XML的configuration的替代吗?

不是完全的,但是与代码结构密切相关的configuration(比如JPA映射或Spring中的dependency injection)通常可以用注释替代,而且通常不会太冗长,烦人和痛苦。 几乎所有值得注意的框架都做了这个转换,尽pipe旧的XMLconfiguration通常仍然是一个选项。

有2个注释的意见

  1. 用户视图,大多数情况下,注释的工作方式就像一个快捷方式,为您节省一些关键笔划,或使您的程序更具可读性

  2. 供应商的观点,处理器的注释视图更多的是轻量级的“接口”,你的程序面对的是SOMETHING,但没有明确地“实现”特定的接口(这里又称注释)

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

 @Entity class Foo {...} 

代替

 class Foo implements Entity {...} 

都说同样的事情“Foo是一个实体类”

像Hibernate这样的框架需要大量的configuration/映射,严重地使用Annotations。

看看Hibernate Annotations

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

这里有几个资源:

  • Sun – Java持久性API
  • Java EE 5教程 – JPA
  • 介绍Java EE 6平台 (检查全部三个页面)。

它不仅是可以被注释接pipe的configuration细节,还可以用来控制行为。 您可以在Java EE 6的JAX-RS示例中看到这一点。

何处可以使用注释

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

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

  • 类实例创buildexpression式:

    新@Interned MyObject();

  • types演员:

    myString =(@NonNull String)str;

  • 实现条款:

    class UnmodifiableList implements @Readonly List <@Readonly T> {…}

  • 抛出的exception声明:

    void monitorTemperature()throws @Critical TemperatureException {…}

在方法,类或字段级别注释你的类是有用的,这个类与这个类没有太大关系。

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

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

它只是另一个工具,它有很多目的。

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

**

  • 以下是内置的注释:: 2种types

**

types1)应用于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"}) 

types2)应用于其他注释的注释:

 @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/

注释可以用作外部configuration文件的替代,但不能被视为完整的replace。 你可以find许多例子,其中annotationi已经被用来替代configuration文件,比如Hibernate,JPA,EJB 3以及Java EE中包含的几乎所有的技术。

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

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

最后,规则永远是一样的:在源头内部保留随着源头而变化的东西,并且保持源头外部独立于源头的东西。

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

Java注释的目的仅仅是将信息与注释的程序元素相关联。 无论是包,类(包括枚举),接口(包括注释types),字段,方法,forms参数,构造函数还是局部variables,Java注释都可以用作修饰符。

Java注释也可以在枚举常量上使用。 这样的注释紧接在他们注释的枚举常量之前。 Java注释通常放置在所有其他修饰符之前,但这不是必需的; 他们可以自由混合其他修饰语。

详细阅读Java注释 。