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

时间:2009-09-03 11:33:10

标签: java annotations

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

15 个答案:

答案 0 :(得分:286)

注释是元元对象,可用于描述其他元对象。元对象是类,字段和方法。向对象请求其元对象(例如anObj.getClass())称为 introspection 。内省可以更进一步,我们可以问一个元对象它的注释是什么(例如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),例如Hibernate,JPA
  • 以及更多...

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

答案 1 :(得分:46)

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

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 :(得分:16)

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

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

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

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

希望我已经向您介绍了如何在不同的框架中使用注释。

答案 3 :(得分:10)

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

此功能通常被Libraries& SDK(hibernate,JUnit,Spring Framework)可以简化或减少程序员除非与这些库或SDK一起工作所需的代码量。因此,公平地说Annotations and Reflection工作是否可行交上Java。

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

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

答案 4 :(得分:6)

  

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

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

答案 5 :(得分:6)

有2个注释视图

  1. 用户视图,大部分时间,注释都像快捷方式一样工作,保存一些击键,或使程序更具可读性

  2. 供应商视图,处理器的注释视图更多是轻量级“接口”,您的程序面对SOMETHING但未明确“实现”特定接口(此处又称注释)

  3. e.g。在jpa中你定义了像

    这样的东西
    @Entity class Foo {...}
    

    而不是

    class Foo implements Entity {...}
    

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

答案 6 :(得分:2)

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

查看Hibernate Annotations

答案 7 :(得分:2)

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

以下是几个资源:

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

答案 8 :(得分:2)

Where Annotations Can Be Used

  

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

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

  • 类实例创建表达式:

    new @Interned MyObject();

  • 输入:

    myString =(@ NonNull String)str;

  • 实现子句:

    类UnmodifiableList实现         @Readonly List&lt; @Readonly T&gt; {...}

  • 抛出的异常声明:

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

答案 9 :(得分:1)

在方法,类或字段级别对类进行注释非常有用,有关该类与该类不太相关的内容。

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

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

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

答案 10 :(得分: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 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/

答案 11 :(得分:0)

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

答案 12 :(得分:0)

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

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

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

最后,规则始终是相同的:在源内保留随源变化的内容,并在源外保留与源独立更改的内容。

答案 13 :(得分:0)

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

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

详细阅读Java Annotations

答案 14 :(得分: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

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

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

相关问题