我们可以使用注释的主要区域是什么?该功能是否可替代基于XML的配置?
注释是元元对象,可用于描述其他元对象。元对象是类,字段和方法。向对象询问其元对象(例如anObj.getClass()
)被称为内省。内省可以更进一步,我们可以问一个元对象它的注释是什么(例如aClass.getAnnotations
)。内省和注释属于所谓的反射和元编程。
需要以某种方式解释注释以使其有用。注释可以在开发时由IDE或编译器解释,也可以在运行时由框架解释。
注释处理是一种非常强大的机制,可以以多种不同的方式使用:
@Deprecated, @Override
,或@NotNull
@Entity, @TestCase, @WebService
@Statefull, @Transaction
@Column, @XmlElement
在所有情况下,注释用于描述元素并阐明其含义。
在JDK5之前,现在用注释表示的信息需要存储在其他地方,并且经常使用XML文件。但是使用注释更方便,因为它们属于Java代码本身,因此比XML更容易操作。
注释的用法:
...看一下项目Lombok,它使用注释来定义如何生成equals
或hashCode
方法。
它可以在方法,类或字段级别对类进行注释,这与该类与该类不太相关的类有关。
您可以拥有自己的注释,用于将某些类标记为仅供测试使用。它可以仅用于文档目的,或者您可以通过在编译生产版本候选者期间过滤掉它来强制执行它。
您可以使用注释来存储一些元数据,例如插件框架,例如插件的名称。
它只是另一种工具,它有很多用途。
它通过(a)编译器检查或(b)代码分析附加有关代码的附加信息
**
**
类型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
更好地了解以下链接:使用示例进行操作
注释可以用作外部配置文件的替代,但不能被视为完全替代。您可以找到许多使用annotationi替换配置文件的示例,例如Hibernate,JPA,EJB 3以及Java EE中包含的几乎所有技术。
无论如何,这并不总是好的选择。使用配置文件的目的通常是将代码与运行应用程序的环境的详细信息分开。在这种情况下,并且主要是在使用配置将应用程序映射到外部系统的结构时,注释不是配置文件的良好替代品,因为它们使您在源代码中包含外部系统的详细信息。你的申请。这里外部文件被认为是最佳选择,否则每次更改执行环境中的相关细节时,您都需要修改源代码并重新编译。
注释更适合于使用额外信息来装饰源代码,这些信息指示处理工具(在编译时和运行时)以特殊方式处理类和类结构。 @Override
和JUnit的@Test
就是这种用法的好例子,已在其他答案中详细解释过。
最后,规则始终是相同的:在源内保留随源变化的内容,并在源外保留与源独立更改的内容。
Java EE 5倾向于使用注释而不是XML配置。例如,在EJB3中,EJB方法的事务属性是使用注释指定的。他们甚至使用注释将POJO标记为EJB,并将特定方法指定为生命周期方法,而不是要求实现接口。
Java注释的目的仅仅是将信息与带注释的程序元素相关联。 Java注释可用作任何声明中的修饰符,无论是包,类(包括枚举),接口(包括注释类型),字段,方法,形式参数,构造函数还是局部变量。
Java注释也可以用在枚举常量上。这些注释紧接在它们注释的枚举常量之前。 Java注释通常放在所有其他修饰符之前,但这不是必需的;它们可以与其他修饰符自由混合。
详细了解Java Annotations。
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) {
...
}
这可能允许编译器警告您有关变量和空值的不正确/未经检查的使用。
另一个更高级的注释应用程序涉及运行时的反射和注释处理。这是(我认为)当您将注释称为“替换基于XML的配置”时您的想法。这是一种注释处理,例如,通过各种框架和JCP标准(持久性,依赖注入,您命名),以提供必要的元数据和配置信息。
注释是添加到Java源文件的元数据(有关数据的数据)的一种形式。框架主要使用它们来简化客户端代码的集成。我脑子里有几个现实世界的例子:
@Test
注释添加到希望JUnit运行器运行的每个测试方法中。设置测试还有其他注释(如@Before
和@BeforeClass
)。所有这些都由JUnit运行程序处理,它运行相应的测试。您可以说它是XML配置的替代品,但注释有时更强大(例如,它们可以使用反射),并且它们更接近它们引用的代码(@Test
注释就在测试方法之前,所以该方法的目的很明确 - 作为文档也是如此)。另一方面,XML配置可能更复杂,并且可以包含比注释更多的数据。@Root
注释告诉Terracotta运行时注释字段是根,其内存应该在VM实例之间共享。 XML配置文件用于配置服务器并告诉它要检测哪些类。@Inject
注释,当应用于构造函数时,Guice运行时会根据定义的注入器查找每个参数的值。 @Inject
注释很难使用XML配置文件进行复制,并且它与它引用的构造函数的接近度非常有用(想象一下,必须搜索一个巨大的XML文件才能找到你设置的所有依赖注入)。希望我已经告诉你如何在不同的框架中使用注释。
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());
}
}
}
test alpha.Java
package io.hamzeen;
import io.hamzeen.IssueInfo;
import io.hamzeen.IssueInfo.Type;
@IssueInfo(type = Type.IMPROVEMENT, reporter = "Hamzeen. H.")
public class TestAlpha {
}
issue info.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的配置的替代品吗?
不完全,但与代码结构紧密对应的配置(例如JPA映射或Spring中的依赖注入)通常可以用注释替换,然后通常不那么冗长,烦人和痛苦。几乎所有值得注意的框架都进行了这种切换,尽管旧的XML配置通常仍然是一种选择。
有2个注释视图
例如在jpa中你定义了类似的东西
@Entity class Foo {...}
代替
class Foo implements Entity {...}
两者都说同样的话“Foo是一个实体类”
注释可以应用于声明:类,字段,方法和其他程序元素的声明。当在声明中使用时,每个注释通常按照惯例出现在它自己的行上。
Java SE 8更新:注释也可以应用于类型的使用。这里有些例子:
像Hibernate这样的框架需要大量的配置/映射使用注释。
JPA(来自Java EE 5)是注释(过度)使用的一个很好的例子。 Java EE 6还将在许多新领域中引入注释,例如RESTful webservices和每个旧的Servlet API下的新注释。
这里有几个资源:
它不仅是注释要接受/可以接管的配置细节,而且它们也可以用于控制行为。您可以在Java EE 6的JAX-RS示例中看到这一点。