批处理注释bat注释一行

在Java中,大多数情况下,批注和批注处理器都被一团谜团包围。 他们似乎是为“专家”保留的主题。最重要的是,我认为他们周围还存在一些FUD 。该职位旨在以尽可能中立的方式深入探讨该主题。这样,每个人都可以做出明智的决定基于事实,而不是聆听充满误解或隐藏议程的人们。

自Java版本5(代号为Tiger)于2004年发布以来,便可以使用注释。

在Java计算机编程语言中,注释是一种语法元数据,可以添加到Java源代码中。 类,方法,变量,参数和Java包可能会带有注释。

—维基百科
https://zh.wikipedia.org/wiki/Java_annotation

最简单的注释如下所示:

Foo.java
@MyAnnotationpublicclassFoo{}

由于缺少注释,以前的Java版本必须以倾斜的方式使用某些功能。

更换标记器接口

自Java诞生以来,就需要标记一个类或类的层次结构。 在Java 5之前,这是通过没有方法的接口完成的。 Serializable和可Cloneable是此类接口的两个示例。

这种接口显然不同于其他接口:它们在自己和实现类之间未定义任何协定。 因此,他们赢得了标记器接口的名称。

Java新手通常会问与该方法有关的问题。 这样做的原因是因为这是一个把戏。 注释消除了对该技巧的需要,并保留了接口的协定角色。

publicclassFooimplementsMarkerInterface{} (1)@MyAnnotation
publicclassFoo{} (2)

  1. 标记界面
  2. 等同于标记界面的注释
更好的元数据管理

弃用是将API标记为过时的过程。 这样,用户可以获知有关更改的信息,可以决定停止使用该API,并且可以在以后的版本中以较小的影响删除该API。 在Java 5之前,JavaDoc中设置了弃用:

/*** Blah blah JavaDoc.** @deprecated As of JDK version 1.1,*/
publicclassDeprecatedApi{}

显然,这是一种非常脆弱的方法:唯一利用它的方法是通过javadoc工具。 标准JavaDocs 专门讨论了这些不推荐使用的API 。 或者,可以通过自定义doclet配置javadoc工具,以以任何所需方式处理Javadoc元数据(包括但不限于@deprecated )。

在Java 5中,已弃用使用提供的@Deprecated批注进行标记:

/*** Blah blah JavaDoc.*/
@Deprecated
publicclassDeprecatedApi{}

旧的不推荐使用的API保留了旧的方法,因此它们同时使用元数据和注释。

此外,由于Java 9, @Deprecated允许两个元素:

可选元素 修饰符和类型 描述

forRemoval

boolean

Indicates whether the annotated element is subject to removal in a future version.

since

String

Returns the version in which the annotated element became deprecated.

@Deprecated(since="1.2",forRemoval=true)
publicabstractclassIdentityScopeextendsIdentity{

创建注释

要创建注释,请使用@interface关键字:

public@interfaceMyAnnotation{}

但是,这还不够,因为不能在任何地方设置这样的注释。 注释需要另外两条信息:

  1. 目标 :定义可以在何处设置注释
  2. 保留 :这说明了注释在编译过程中的哪个步骤可用

稍后我们将详细介绍。 到目前为止,我们首先需要了解注释的工作方式。 当类从其父类继承代码时,将注解为

@Target(ElementType.ANNOTATION_TYPE) (1)
@interfaceFoo{}@Target(ElementType.ANNOTATION_TYPE) (1)
@interfaceBar{}@Foo
@Bar
@interfaceBaz{} (2)

  1. 这是必需的@Target ,将在@Target进一步解释
  2. @Baz注释的内容同时用@Foo@Bar注释

这是@Target@Retention的源代码:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public@interfaceTarget{ (1)ElementType[]value();
}@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public@interfaceRetention{ (2)RetentionPolicyvalue();
}

  1. @Target注释告诉您可以在哪个元素上设置注释:

    • 在类型上, 例如类或接口
    • 在另一个注释上
    • 在田野上
    • 在方法上
    • 在构造函数上
    • 在方法参数上
    • 在局部变量上
    • 在模块上
    • 等等
  2. @Retention注释定义了注释在编译过程中的哪个步骤可用:
    • 仅源代码
    • 在类文件中
    • 在运行时

下面的类图中对此进行了总结:

注释参数

注释可以定义参数 。 使用注释时,可以使用参数添加某些级别的配置。 参数接受类型和可选的默认值 。 如果在定义注释时未设置该值,则必须在使用它时使用。

参数类型限于以下几种:

  • 任何原始类型, 例如 intlong等。
  • String
  • Class<T>
  • 任何enum类型
  • 另一种注释类型
  • 以上任何数组
@Target(ElementType.CLASS)
@interfaceFoo{intbar();Class<?extendsCollection>baz()defaultList.class;String[]qux();
}@Foo(bar=1,qux={"a","b","c"})
classMyClass{}

如果只有一个参数并将其命名为value ,则在设置时可以省略其名称:

@Target(ElementType.CLASS)
@interfaceFoo{intvalue();
}@Foo(1)
classMyClass{}

在运行时处理批注:反射

自创建以来,Java就允许反射 :反射是在运行时获取有关代码信息的能力。 这是一个示例:

varsession=request.getHttpSession();
varobject=session.getAttribute("objet"); (1)
varclazz=object.getClass(); (2)
varmethods=clazz.getMethods(); (3)
for(varmethod:methods){if(method.getParameterCount()==0){ (4)method.invoke(foo); (5)}
}

  1. 获取存储在会话中的对象
  2. 获取对象的运行时类
  3. 获取对象上所有可用的public方法
  4. 如果该方法没有参数
  5. 调用方法

通过注释,反射API得到了相关的改进:

通过注释,框架开始在不同的用例中使用它们。 其中,配置是最常用的配置之一:例如, Spring框架代替了XML(或者更精确地说,除了XML之外),还添加了基于注释的配置选项。

在编译时处理批注:批注处理器

长期以来,用户和提供者都对运行时反射对批注的访问感到满意。 因为它主要集中在配置上,所以反射在启动时发生。 在受限的环境中,这对应用程序来说负担太重:此类环境最著名的示例是Android平台。 人们可能希望在那里拥有最快的启动时间,而启动时间反射方法会使速度变慢。

解决该问题的另一种方法是在编译时处理注释 。 为此,必须将编译器配置为使用特定的注释处理器 。 它们的输出可能不同:简单的文件,生成的代码等。这种方法的权衡之处在于, 每次编译都会对性能造成影响,但不会影响启动时间。

使用此方法生成代码的最早框架之一是Dagger :它是Android的DI框架。 它不是基于运行时的,而是基于编译时的。 长期以来,编译时代码生成仅限于Android生态系统。

但是,最近,诸如Quarkus和Micronaut之类的后端框架也采用了这种方法。 目的是通过编译时代码生成来代替运行时自省,以减少应用程序启动时间。 此外,将生成的字节码提前编译为本机代码还可以进一步减少启动时间以及内存消耗。

注释处理器的世界非常庞大:本节只是一个很小的介绍,因此如果需要,可以继续进行。

处理器只是需要在编译时注册的特定类。 有几种注册方法。 使用Maven,只需配置编译器插件即可:

pom.xml
<build><plugins><plugin><groupId> org.apache.maven.plugins </groupId><artifactId> maven-compiler-plugin </artifactId><version> 3.8.1 </version><configuration><annotationProcessors><annotationProcessor> ch.frankel.blog.SampleProcessor </annotationProcessor></annotationProcessors></configuration></plugin></plugins>
</build>

处理器本身需要实现Processor ,但是抽象类AbstractProcessor实现其大多数方法,但可以进行process :实际上,从AbstractProcessor继承就足够了。 这是API的简化图:

让我们创建一个非常简单的处理器。 它只应列出带有特定注释的类。 现实世界中的注释处理器可能会做一些有用的事情, 例如生成代码,但是这种额外的逻辑远远超出了本文的范围。

@SupportedAnnotationTypes("ch.frankel.blog.*") (1)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
publicclassSampleProcessorextendsAbstractProcessor{@Overridepublicbooleanprocess(Set<?extendsTypeElement>annotations, (2)RoundEnvironmentenv){annotations.forEach(annotation->{ (3)Set<?extendsElement>elements=env.getElementsAnnotatedWith(annotation); (4)elements.stream().filter(TypeElement.class::isInstance) (5).map(TypeElement.class::cast) (6).map(TypeElement::getQualifiedName) (7).map(name->"Class "+name+" is annotated with "+annotation.getQualifiedName()).forEach(System.out::println);});returntrue;}
}

  1. 属于ch.frankel.blog包的每个注释都将调用处理器
  2. process()是重写的主要方法
  3. 将为每个注释调用循环
  4. 注释不像使用注释的元素那么有趣。 这是获取带注释元素的方法。
  5. 根据要注释的元素,需要将其强制转换为正确的Element子接口。 在这里,只能注释类,因此,需要对变量进行测试,以检查其是否可分配的TypeElement才能在操作链的更下方访问其附加属性。
  6. 我们希望设置注释的类的合格名称,因此有必要将其强制转换为可访问此特定属性的类型
  7. TypeElement获取合格名称

结论

无论在运行时还是在编译时使用,注释都非常强大。 另一方面,最大的问题是它们似乎像魔术一样工作:没有简单的方法来知道哪个使用反射的类或注释处理器正在使用它们。 每个人都可以根据自己的情况决定自己的优点是否超过缺点。 在没有任何深思熟虑的情况下使用它们会对代码产生极大的损害....由于意识形态错位而导致丢弃它们与破坏代码一样严重。

我希望这篇文章对注释的工作方式有所启发,以便大家自己决定。

可以在Github上以Maven格式找到此帖子的完整源代码。

更进一步:

  • Java中的标记接口
  • Doclet概述
  • Java语言规范:注释类型
  • Java语言规范:注释
  • Trail:反射API
  • Java注释处理和创建生成器

翻译自: https://blog.frankel.ch/introductory-guide-annotation-processor/

批处理注释bat注释一行

批处理注释bat注释一行_注释和注释处理器入门指南相关推荐

  1. excel批注不显示批注框_批注和批注处理器入门指南[解释]

    excel批注不显示批注框 在Java中,大多数情况下,批注和批注处理器都被一团谜团包围. 他们看起来像是为"专家"保留的主题. 最重要的是,我相信他们周围也有一些FUD. 这篇文 ...

  2. 群晖nas介绍文档_群晖 NAS 选购 入门指南:动手打造自己的家庭数据中心

    原标题:群晖 NAS 选购 & 入门指南:动手打造自己的家庭数据中心 Matrix 精选 Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考.我们会不定期挑选 ...

  3. apex您所在的地区目前不提供此物品_《APEX英雄》入门指南传奇篇-命脉

    <Apex英雄>是"大逃杀"类游戏中的全新之作,传奇篇指南将带你了解每位传奇的独特技能,并分析技能的使用方式及时机. 本篇中传奇名及技能名将使用简体版本. 命脉-战斗医 ...

  4. 渲染管线_高清晰度渲染管线:艺术家入门指南

    渲染管线 In this post we will explore authoring a scene to be rendered using Unity's High Definition Ren ...

  5. python怎么返回上一行代码_Python实现判断一行代码是否为注释的方法

    目前的编辑器大都可以自动检测某一行代码是否为代码行或注释行,但并不太提供代码行/注释行行数的统计,对于大量代码文件的代码行/注释行统计,就更少见一些.本篇文章试用一段Python脚本来实现这一目标,并 ...

  6. 在python中可以使用if作为变量名_变量,注释,缩进,细数Python优雅风 | Python基础连载(二)...

    开篇 在之后的几期文章中,你将会陆续学习到Python的六个标准数据类型 不过在此之前,有一些先导内容需要掌握,所以这一期就先来介绍一下这些内容. 文章首发于微信公众号:我将在南极找寻你.专注干货分享 ...

  7. vscode 注释多行代码_如何在Visual Studio Code中注释多行?

    我找不到在Visual Studio Code中注释和取消注释多行代码的方法. 是否可以使用某些快捷方式在Visual Studio Code中注释和取消注释多行? 如果是,该怎么办? 当其中一行已被 ...

  8. java 缩进_java编码规范_缩进和注释

    1.       缩进排版(Indentation) 4个空格常被作为缩进排版的一个单位.缩进的确切解释并未详细指定(空格 vs. 制表符).一个制表符等于n个空格(视具体的编辑器而定,Eclipse ...

  9. java注释还能运行_老师,你确定Java注释不会被执行吗?

    之前在博客上分享过一篇文章,涉及到 Java 中的注释,就信誓旦旦地写了一句话:"注释是不会被执行的!"结果,有小伙伴留言说,"老师,你确定吗?" 我这个人一直 ...

  10. r语言工作路径linux,R语言实用基础知识_工作路径-注释-安装和卸载R包_2019-12-01...

    R语言的实用基础知识有很多,都是我在工作和学习中所整理的,有的是看书整理的,也有的是从网络上的各种博客.各种资源获取的,所以我采用日更的方式进行支持整理和更新,希望能够帮到屏幕前的你! 今天是我日更的 ...

最新文章

  1. 一键ghost奥运版_超详细的纯净版windows系统重装示例
  2. Service Fabric独立集群搭建
  3. python常用内置函数总结-Python 常用内置函数
  4. Python零碎知识(8):模块的学习|资源利用
  5. DL框架:主流深度学习框架(TensorFlow/Pytorch/Caffe/Keras/CNTK/MXNet/Theano/PaddlePaddle)简介、多个方向比较、案例应用之详细攻略
  6. 发现程序美----while+for冒泡实现的
  7. asp.net MVC5为WebAPI添加命名空间的支持
  8. 【C++】 67_经典问题分析 五
  9. java计算器算法描述_基于Java的计算器算法(源代码)
  10. onInterceptTouchEvent / onTouchEvent响应事件的详析
  11. .Net Micro Framework研究—带I2C总线的模拟器
  12. import和__import__()有什么不同?
  13. 单设施布置方法-精确重心法
  14. 单片机STM32开发环境的安装
  15. 计算机系统中的数据计量单位-位(bit)、字节(Byte)、字(word)
  16. 威联通TS231nas虚拟服务器,威联通NAS小技巧:自带VS3软件下安装win7虚拟机
  17. F-score is ill-defined and being set to 0.0 due to no predicted samples.
  18. 网站443端口经常受到攻击怎么办
  19. 词法语法分析器EDG C++
  20. Python 位操作符(Bitwise)

热门文章

  1. J-Link驱动安装
  2. python 实现 pdf 书签读取、批量写入
  3. Java中的list集合排序方法
  4. 苹果录屏没声音_通过AppleALC,轻松解决黑苹果没声音问题
  5. ftp连接530错误
  6. CAN通信协议(一)
  7. SPSS操作(五):主成分分析
  8. java面试题:数组的常用算法实现
  9. w ndows7旗舰版怎么重装系统,windows7旗舰版怎么重装系统|怎么重装系统windows7旗舰版...
  10. 电脑开机出现press f11 to start recovery system问题分析与解决