您现在的位置:首页行业资讯

注释在Java中如何工作?--中享思途

注释一直是Java的一个非常重要的部分,并且从J2SE 5.0开始就已经存在。我们所有人都 在某个地方或其他地方在我们的应用程序代码中看到了@Override 和这样的注释    @Deprecated。在本文中,我将讨论注释的确切含义,引入的原因,它们的工作方式,如何编写自定义注释(带有示例代码),可能有效的注释方案,最后是注释和ADF。这将是一篇很长的文章,所以请喝点咖啡,准备好进入注释世界。
   什么是注释?
   解释注释的一个词是元数据。元数据是关于数据的数据。因此,注释是代码的元数据。例如,看下面的代码。
   @Override
   public String toString() {
   return "This is String Representation of current object.";
   }
   我已经覆盖了 上面的代码中的 toString() 方法并使用了  @Override注释。即使我不放 @Override,代码也可以正常工作而没有任何问题。那么,此注释的优点是什么?  @Override 告诉编译器此方法是重写的方法(有关该方法的元数据),并且如果父类中不存在任何这样的方法,则抛出编译器错误(方法不会从其超类中重写方法)。现在,如果我犯了一个印刷错误,并且将方法名称用作  toStrring() {double r},并且如果我不使用 @Override,则我的代码将成功编译并执行,但是结果将与我接受的结果不同。所以现在,我们了解了什么是批注,但是阅读正式定义还是不错的
   注释是一种特殊的Java构造,用于装饰类,方法,字段,参数,变量,构造函数或包。它是JSR-175选择提供元数据的工具。
   为什么要引入注释?
   在注释之前(甚至之后),XML被广泛用于元数据,并且以某种方式,一组特定的应用程序开发人员和架构师认为XML维护变得越来越麻烦。他们想要的东西可以与代码而不是XML紧密结合,而XML与代码之间的联系非常松散(在某些情况下,几乎是分开的)。如果您搜索“ XML与注释”,您会发现很多有趣的争论。有趣的一点是,引入了XML配置以将配置与代码分开。最后两个语句可能会在您的脑海中产生一些疑问,因为这两个语句正在创建一个周期,但是两者各有利弊。让我们尝试通过一个例子来理解。
   假设您要设置一些应用程序范围的常量/参数。在这种情况下,XML是一个更好的选择,因为它与任何特定的代码段都不相关。如果要将某个方法作为服务公开,则注释将是一个更好的选择,因为它需要与该方法紧密结合,并且方法的开发人员必须意识到这一点。
   另一个重要因素是,注释定义了在代码中定义元数据的标准方法。在注释之前,人们还使用自己的方式定义元数据。一些示例使用标记界面,注释,临时关键字等。每个开发人员都需要用自己的方式来决定元数据,但要注释标准化的东西。
   如今,大多数框架都将XML和注解结合使用,以充分利用两者的积极方面。
   批注的工作方式以及如何编写自定义批注
   在开始解释之前,建议您下载此注释示例代码(AnnotationsSample.zip)并在您选择的任何IDE中保持打开状态,因为这将帮助您更好地理解以下说明。
   编写注释非常简单。您可以将注释定义与接口定义进行比较。让我们看两个示例-一个是标准  @Override 注释,另一个是自定义注释@Todo:
   @Target(ElementType.METHOD)
   @Retention(RetentionPolicy.SOURCE)
   public @interface Override {
   }
   似乎有些可疑@Override; 它没有做任何事情-它只是检查看是否在父类中定义了一个方法。好吧,不要惊讶。我不是在开玩笑。覆盖注释的定义仅包含那么多代码。这是最重要的部分,我要重申一下:注释只是元数据,不包含任何业务逻辑。很难消化,但确实如此。如果注释不包含逻辑,则其他人必须在做某事,并且某人是此注释元数据的使用者。注释仅提供有关在其上定义属性的信息(类/方法/包/字段)。使用者是一段代码,它读取此信息,然后执行必要的逻辑。
   当我们谈论诸如之类的标准注释时  @Override,  JVM是使用者,它在字节码级别工作。现在,这是应用程序开发人员无法控制并且不能用于自定义注释的功能。因此,我们需要自己给消费者写注释。
   让我们一一理解用于注释的关键术语。在以上示例中,您将看到在批注中使用了批注。
   J2SE 5.0在java.lang.annotation包中提供了四个注释,这些注释仅在编写注释时使用:
   @Documented–是否在Javadocs中添加注释
   @Retention–需要注释时
   @Target?–放置注释的位置
   @Inherited–子类是否获得注释。
   @Documented–一个简单的市场注释,告诉您是否要在Java文档中添加注释。
   @Retention–定义注释应保留多长时间。
   RetentionPolicy.SOURCE–编译期间丢弃。这些注释在编译完成后没有任何意义,因此不会写入字节码。范例:   @Override, @SuppressWarnings
   RetentionPolicy.CLASS–在上课时丢弃。在进行字节码级后处理时很有用。令人惊讶的是,这是默认设置。
   RetentionPolicy.RUNTIME–不要丢弃。注释应可在运行时用于反射。这就是我们通常用于自定义注释的内容。
   @Target–可以放置注释的位置。如果未指定,则注释可以放置在任何地方。以下是有效值。这里的一个重要点是它仅包含所有内容,这意味着如果要对7个属性进行批注,而只想排除一个属性,则在定义目标时需要包括所有7个属性。
   ElementType.TYPE(类,接口,枚举)
   ElementType.FIELD(实例变量)
   ElementType.METHOD
   ElementType.PARAMETER
   ElementType.CONSTRUCTOR
   ElementType.LOCAL_VARIABLE
   ElementType.ANNOTATION_TYPE(在另一个注释上)
   ElementType.PACKAGE(记住package-info.java)
   @Inherited–控制注释是否应影响子类。
   现在,注释定义里面有什么?注释仅支持原语,字符串和枚举。注释的所有属性都定义为方法,还可以提供默认值
   @Target(ElementType.METHOD)
   @Retention(RetentionPolicy.RUNTIME)
   @interface Todo {
   public enum Priority {LOW, MEDIUM, HIGH}
   public enum Status {STARTED, NOT_STARTED}
   String author() default "Yash";
   Priority priority() default Priority.LOW;
   Status status() default Status.NOT_STARTED;
   }
   以下是如何使用上述注释的示例:
   @Todo(priority = Todo.Priority.MEDIUM, author = "Yashwant", status = Todo.Status.STARTED)
   public void incompleteMethod1() {
   //Some business logic is written
   //But it’s not complete yet
   }
   如果注释中只有一个属性,则应将其命名为“值”,并且在使用它时可以不使用属性名称。
   @interface Author{
   String value();
   }
   @Author("Yashwant")
   public void someMethod() {
   }
   到目前为止,一切都很好。我们已经定义了定制注释,并将其应用于某些业务逻辑方法。现在,该写一个消费者了。为此,我们将需要使用反射。如果您熟悉反射代码,则知道反射提供了类,方法和字段对象。所有这些都有一个  getAnnotation()   方法,该方法返回注释对象。我们需要将此对象强制转换为自定义注释(使用进行检查后instanceOf()),然后才能调用自定义注释中定义的方法。让我们看一下使用上面的注释的示例代码:
   Class businessLogicClass = BusinessLogic.class;
   for(Method method : businessLogicClass.getMethods()) {
   Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);
   if(todoAnnotation != null) {
   System.out.println(" Method Name : " + method.getName());
   System.out.println(" Author : " + todoAnnotation.author());
   System.out.println(" Priority : " + todoAnnotation.priority());
   System.out.println(" Status : " + todoAnnotation.status());
   }
   }
   注释用例
   注释功能非常强大,Spring和Hibernate之类的框架将注释广泛用于日志记录和验证。注释可以在使用标记接口的地方使用。标记接口用于完整的类,但是您可以定义可以在单个方法上使用的注释,例如,某个方法是否作为服务方法公开。
   在Servlet规范3.0中,引入了许多注释,尤其是与Servlet安全性相关的注释。让我们看看一些:
   HandlesTypes–此注释用于声明传递给的应用程序类的数组  ServletContainerInitializer。
   HttpConstraint-该注释表示被施加到与HTTP协议方法类型的所有请求未否则通过相应的表示的安全约束  HttpMethodConstraint 的  ServletSecurity 注释。
   HttpMethodConstraint–特定的安全约束可以应用于不同类型的请求,通过在注释内部使用此注释,可以根据HTTP协议方法类型进行区分  ServletSecurity 。
   MultipartConfig–该注释用于指示声明了它的Servlet希望使用multipart / form-data MIME类型进行请求。
   ServletSecurity–在Servlet实现类上声明此注释,以对HTTP协议请求强制实施安全性约束。
   WebFilter–用于声明Servlet过滤器的注释。
   WebInitParam–用于在WebFilter 或  WebServlet 注释内的Servlet或过滤器上声明初始化参数的  注释。
   WebListener— 在给定的Web应用程序上下文中用于声明各种事件的侦听器的注释。
   WebServlet–此注释用于声明Servlet的配置。
   ADF(应用程序开发框架)和注释
   现在,我们处于讨论的最后部分:应用程序开发框架,也称为ADF。ADF由Oracle开发,用于构建Oracle Fusion Applications。我们已经看到了优点和缺点,并且知道如何编写自定义注释,但是在ADF中可以在哪里使用自定义注释呢?ADF是否提供任何本机注释?
   这些肯定是有趣的问题:但是,是否存在某些限制会阻止在ADF中大规模使用注释?前面提到的框架(如Spring和Hibernate)使用AOP(面向方面的编程)。在AOP中,该框架提供了一种机制,可以为任何事件注入用于预处理和后处理的代码。例如,您具有在方法执行前后放置代码的钩子,因此可以在这些位置编写使用者代码。ADF不使用AOP。如果我们有任何有效的注释用例,则可能需要通过继承方法。

【关键词:青岛Java培训,Java就业培训,学Java开发多少钱,Java培训哪家好,中享思途】

 st_bottom
青岛Java培训,青岛HTML5培训,青岛UI培训,青岛web开发培训,青岛IT培训,java培训,ui培训,HTML5培训,java就业培训,专业ui设计,web开发培训,IT培训,思途教育,青岛思途,中享思途
Copyright © 青岛思途共享科技信息服务有限公司 鲁ICP备14027489号-2

鲁公网安备 37021402000988号

青岛Java培训,青岛HTML5培训,青岛UI培训,青岛web开发培训,青岛IT培训,java培训,ui培训,HTML5培训,java就业培训,专业ui设计,web开发培训,IT培训,思途教育,青岛思途,中享思途