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

Bij*_* CD 203 java annotations

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

ewe*_*nli 298

注释是元元对象,可用于描述其他元对象.元对象是类,字段和方法.向对象询问其元对象(例如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项目中查看,该项目使用注释来定义如何生成equalshashCode方法.


Dir*_*irk 46

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

class Foo {

    @Override public boolean equals(Object other) {
        return ...;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

class Foo {

    @Override public boolean equals(Foo other) {  // Compiler signals an error for this one
        return ...;
    }
}
Run Code Online (Sandbox Code Playgroud)

即将推出的JDK7将允许任何类型的注释.已经有建议将此功能用于编译器注释,例如NotNull,如:

public void processSomething(@NotNull String text) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

这可能允许编译器警告您有关变量和值的不正确/未经检查的使用.

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


Fla*_*gan 17

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

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

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

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

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


Ham*_*eem 11

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

这个特性经常被Libraries&SDKs(hibernate,JUnit,Spring Framework)利用,以简化或减少程序员除非与这些库或SDK一起工作所需的代码量.因此,可以说Annotations和反思在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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

TestAlpha.java

package io.hamzeen;

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

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

}
Run Code Online (Sandbox Code Playgroud)

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";
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*rdt 6

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

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


Dap*_*eng 6

有2个注释视图

  1. 用户视图,大多数时候,注释就像一个快捷方式,保存一些击键,或使您的程序更具可读性

  2. 供应商视图,处理器的注释视图更多是轻量级的"接口",您的程序面对SOMETHING但没有明确"实现"特定的接口(这里也称为注释)

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

@Entity class Foo {...}
Run Code Online (Sandbox Code Playgroud)

代替

class Foo implements Entity {...}
Run Code Online (Sandbox Code Playgroud)

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