我们可以使用注释的主要领域是什么?该特性是基于XML的配置的替代品吗?


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标准(持久性、依赖项注入等等)都使用这种注释处理,以便提供必要的元数据和配置信息。


它对于注释类非常有用,无论是在方法、类或字段级别,都是关于类的一些与类不太相关的东西。

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

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

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


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

JUnit 4 - you add the @Test annotation to each test method you want the JUnit runner to run. There are also additional annotations to do with setting up testing (like @Before and @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 @Test annotation 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 @Root annotation 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 @Inject annotation, which when applied to a constructor makes the Guice runtime look for values for each parameter, based on the defined injectors. The @Inject annotation 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).

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


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

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


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


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

看一看Hibernate注解


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

这里有一些资源:

Sun - Java持久性API Java EE 5教程- JPA 介绍Java EE 6平台(查看所有三个页面)。

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


注释有两个视图

在用户视图中,大多数时候,注释就像一个快捷键,为你节省一些按键,或使你的程序更具可读性 从供应商的角度来看,处理器对注释的看法更像是一个轻量级的“接口”,你的程序确实要面对一些东西,但没有显式地“实现”特定的接口(这里也就是注释)。

例如,在jpa中,您可以定义如下内容

@Entity class Foo {...}

而不是

class Foo implements Entity {...}

两者都说了同样的话"Foo是一个实体类"


注释可以用作外部配置文件的替代品,但不能被视为完全替代。您可以找到许多使用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.

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

最后,规则总是一样的:把随源代码一起变化的东西放在源代码内部,把独立于源代码变化的东西放在源代码外部。


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

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

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

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

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

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

注释的使用:

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

...比如Lombok项目,它使用注释来定义如何生成equals或hashCode方法。


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


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

这个特性,经常被库和sdk (hibernate, JUnit, Spring Framework)利用来简化或减少程序员在使用这些库或sdk时需要做的代码量。因此,可以公平地说,注释和反射在Java中是齐头并进的。

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

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

注释可以在哪里使用

注释可以应用于声明:类、字段、方法和其他程序元素的声明。在声明上使用时,根据约定,每个注释通常出现在自己的行上。

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

类实例创建表达式: @Interned MyObject(); 类型转换: myString =(@非空字符串)str; 实现条款: 类UnmodifiableList实现 @Readonly List<@Readonly T>{…} 抛出的异常声明: void monitorTemperature()抛出 @临界温度异常{…}


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

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

有关注释的更多详细信息,请参考此链接。

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