J2SE 5中注释的引入改变了我们编写和处理Java的方式。 除了Java SE的预定义注释外 ,框架,IDE和工具包还引入了自己的自定义注释 。 Checker框架提供了一些示例,说明如何使用自定义注释在Java中增加类型安全性 。 在本文中,我着眼于编写一个简单的自定义批注并将其在NetBeans ( 8.0.2 )和IntelliJ IDEA ( 14.0.3 )中使用,以帮助开发人员确定其代码中需要进一步注意的问题。
在文章充分利用Java的元数据,第2部分:自定义注释中 , Jason Hunter演示了@Unfinished
注释,作为编写自定义Java注释的示例。 我将在本文中演示@Unfinished
注释的其他实现。 这就是自定义注释的美:可以编写一个最适合自己需求的注释。 我的@Unfinished
批注的代码显示在下一个代码清单中。
Unfinished.java:定义自定义@Unfinished批注
package dustin.examples.annotations;import static java.lang.annotation.ElementType.*;import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** Example of a custom annotation that marks Java code constructs* that are not yet completed.** Notes about custom annotations specific to this example:* - @Documented indicates available for public documentation* - CLASS retention policy means that compiler places annotation* information in compiled .class files, but JVM is NOT aware* of the annotation at runtime.* - @Target parameters (statically imported) indicate that this* annotation can be applied to constructors, fields,* local variables, methods, packages, parameters, and* classes/interfaces.* - Methods defined for this @interface without 'default' are* required settings for application of this annotation. In* this case, the "finishBy" element is NOT required (but* recommended!) but the "value" element is required.* - "value" element has special significance in custom Java* annotations: it is the assumed annotation element if* a String is provided to the annotation without explicit* element name called out.*/
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({CONSTRUCTOR,FIELD,LOCAL_VARIABLE,METHOD,PACKAGE,PARAMETER,TYPE})
public @interface Unfinished
{/** Description of the unfinished construct. */String value();/*** Date, build, or event by which the annotated construct* is anticipated to be finished.*/String finishBy() default "Unknown";
}
下一个代码清单在一个简单的类中显示了@Unfinished
应用程序,还有很多工作要做。
WorkInProgress.java:应用@未完成的自定义批注
package dustin.examples.annotations.demo;import dustin.examples.annotations.Unfinished;/*** Demonstrates custom Java annotation @Unfinished.*/
public class WorkInProgress
{@Unfinished("This will do something good by Revision 2.")public void doSomethingGood(){}@Unfinished(value = "Do something good here.", finishBy = "Revision 2")public void doSomethingElseGood(){}
}
默认情况下,不完整类将注释的“ value”元素用于一种方法,然后将“ finishedBy”元素用于第二种方法。 从最后两个代码清单的定义或@Unfinished
使用可以@Unfinished
:
- 注释元素包含“默认”意味着不需要使用注释的人为该元素提供值。
- 如果仅为注释提供一个值,并且没有明确的元素名称,则假定为“值”元素。
- 如果仅指定一个注释元素,则不需要提供名称“值”,但如果指定了多个注释元素,则必须提供名称。
- 之所以在这里使用CLASS的保留级别,是因为我觉得使用Java类的编译版本的工具将能够使用此信息,并且我预计该信息不会在运行时使用。
- 最好仔细选择哪些注释元素应具有“默认”值,因为不具有“默认”值需要指定一个元素,这在某些情况下可能是所需的行为。
自定义批注的使用可以为其他开发人员和工具提供一种标准化的机制,以构建“可执行的”和更受控制的描述。 与留下带有评论的消息相比,此方法通常是有利的,因为评论的标准化程度较低,并且容易出现拼写错误和区分大小写,拼写和其他差异的情况。 与解析任意文本相比,注释可以更好地执行约定,并允许工具更有效地利用它们传达的内容。 获得自定义注释相对于任意注释的某些好处的最明显的方法可能是使用注释处理器。 多个IDE和框架(例如Checker Framework)处理注释。 关于编写自定义批注处理器的在线参考文献也很多,可与Jav编译器一起使用以提供警告。 在本文的其余部分中,我将重点介绍如何应用两个较流行的Java IDE( NetBeans和IntelliJ IDEA )来将这些注释报告为提示/检查。 在这篇文章中,我并不是在将注解处理器集成到IDE的编译过程中,也不是在将自定义处理器与命令行Java编译器集成。
在NetBeans中检查@未完成的注释
我之前曾写过有关创建NetBeans 7.1自定义提示的博文,该过程与NetBeans 8几乎相同。第一步是使用Refactor-> Inspect and Transform…选项,如下面的屏幕快照所示。
当选择Refactor-> Inspect and Transform…时 ,将显示如下所示的弹出窗口。
我将把这个新检查应用于所有打开的项目,如上一个屏幕快照的“检查”字段所示。 单击“ 浏览 ”按钮,将弹出“ 管理检查 ”窗口,如下一个屏幕快照所示。
点击“ New… ”按钮,允许开发人员在Custom-> Inspection下创建自定义检查。
您可以单击“编辑脚本”按钮来创建自定义检查,其中包括重命名检查的功能。 我已将检查重命名为“未完成的代码”。 下一个屏幕快照显示了我添加到“未完成代码”检查中的代码。
在此“未完成代码”检查的脚本代码中(也显示在下面)中,说明指定为“未完成代码”。 源模式指定为@dustin.examples.annotations.Unfinished($parameters$)
(定义自定义注释的@interface
的整个包名称,其中$parameters$
表示一个或多个参数)。 =>
符号指向目标模式。 在这种情况下,目标模式为空,表示建议的转换将删除@Unfinished
批注。 有关NetBeans检查编辑器语法的更多详细信息,请参见Geertjan Wielenga的NetBeans IDE 7.1中的Custom Declarative Hints 。
<!description="Unfinished Code">
@dustin.examples.annotations.Unfinished($parameters$)
=>
;;
创建NetBeans检查后,就该尝试一下了。 接下来的两个屏幕快照演示了如何选择要运行的检查以及运行结果。
运行检查的结果是一个示例,说明了我们如何结合使用NetBeans和自定义注释来快速标识带注释的代码并对其进行适当处理。
在IntelliJ IDEA中检查@未完成的注释
在IntelliJ IDEA中开始创建自定义批注的一种方法是打开“ 分析->检查代码…” ,然后单击“ 指定检查范围 ”弹出窗口中的“…”按钮,如以下两个屏幕快照所示。
下一个屏幕快照显示“ 检查 ”对话框。
刚刚显示的屏幕快照表明未选中“ 结构搜索检查 ”。 选中该复选框(名称“ Structural Search Inspection”右侧的复选框)将导致“ Severity”级别可以选择,并允许添加特定的检查(加号从灰色变为绿色)。
单击绿色加号( +
),有两个选择:“添加搜索模板…”或“添加替换模板…”。 这里的区别类似于NetBeans在Source-> Inspect and Refactor-> Inspect and Transform…之间的区别。在这里,我将重点介绍“ Replace template ”。
选择“添加替换模板…”时,将显示“ 结构替换 ”对话框。
在这里创建自定义检查的最简单方法是适应现有模板。 单击“ 复制现有模板... ”按钮即可完成此操作。 对于为此博客文章创建的两次检查,我分别复制了现有模板的“带注释的类 ”和“带注释的方法 ”,以创建自己的自定义模板“未完成的类”和“未完成的方法”。
上面的屏幕快照显示了我复制的“现有模板”,下面的屏幕快照显示了我从中为“未完成的类”和“未完成的方法”创建的自定义模板。
对于每个自定义模板(“未完成的类”和“未完成的方法”),我需要单击“ 编辑变量... ”按钮,并为每个变量(正反两面标有$的标识符)指定正则表达式。搜索。 对于大多数变量(例如类名,方法名等),我使用“所有字符”正则表达式( 。* ),但是对于每个模板中的$Annotation$
,我均使用dustin.examples.annotations.Unfinished
。 下一个屏幕快照是该快照的代表性示例,其中显示了“未定义方法”模板的注释变量设置。
我可以使用分析->按名称运行检查...来运行我的任何新检查。 接下来的三个屏幕快照演示了如何运行新的“未完成的方法”检查。
运行检查的结果是一个示例,说明了如何结合使用IntelliJ IDEA和自定义批注来快速识别已批注的代码并对其进行适当处理。
结论
这篇文章演示了使用NetBeans和IntelliJ IDEA的功能来创建自定义检查,以创建检查来警告开发人员其代码中存在自定义注释。 该帖子演示了一个简单的@Unfinished
批注,以及如何在NetBeans和IntelliJ IDEA中应用自定义检查以帮助识别使用这些批注的代码。
翻译自: https://www.javacodegeeks.com/2015/11/applying-ide-inspections-to-custom-java-annotations.html