《Java编程思想》笔记20-注解
Java SE5 内置了三种,定义在 java.lang 中的注解:
@Override
,表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示。@Deprecated
,如果程序员使用了注解为它的元素,那么编译器会发出警告信息(过时)@SuppressWarnings
,关闭不当的编译器警告信息。在 Java SE5 之前的版本中,也可以使用该注解,不过会被忽略不起作用。
每当你创建描述符性质的类或接口时,一旦其中包括了重复性的工作,那就可以考虑使用注解来简化与自动化该过程。
定义注解
注解的定义很像接口的定义,也会编译成 class 文件。注解不支持继承。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public int id();
public String description() default "no description"; // 默认值
}
public class PasswordUtils {
@UseCase(id=47, description="description")
public boolean validatePassword(String password) {
return (password.matches("\\w*\\d\\w*"));
}
@UseCase(id = 48)
public String encryptPassword(String password) {
return new StringBuilder(password).reverse().toString();
}
}
定义默认值时,不能以 null 作为其值。一般可以自己定义一些特殊的值,如空字符或负数,表示某个元素不存在。
元注解
注解 | 说明 |
---|---|
@Target | 定义注解应用的地方。ElementType 参数包括:CONSTRUCTOR :构造器的声明;FIELD :域声明(包括 enum 实例);LOCAL_VARIABLE :局部变量声明;METHOD :方法声明;PACKAGE :包声明;PARAMETER :参数声明;TYPE :类、接口或enum声明 |
@Retention | 定义注解应用的级别。RetentionPolicy 参数包括:SOURCE :注解将被编译器丢弃;CLASS :注解在 class 文件中可用,但会被 VM 丢弃;RUNTIME :VM 将在运行期也保留注解,因此可通过反射机制读取注解信息 |
@Documented | 将此注解包含在 JavaDoc 中 |
@Inherited | 允许子类继承父类中的注解 |
ElementType 参数,可以只指定某一个值,也可以以逗号分隔的形式指定多个值,如果想将注解应用于所有的 ElementType,那么可以省去 @Target
元注解,不过不常用。
注解元素
注解元素可用的类型包括:
- 所有基本类型
- String
- Class
- enum
- Annotation
- 所有前面这些类型的数组
不允许使用任何包装类型(有自动装箱存在,所以算不上什么限制),注解可以嵌套。
如果元素值是一个数组,要将它的值用大括号括起来 @Test(array={"a","b"})
,如果只有一个值,也可以省去括号。
注解中定义了名为 value
的元素,且在应用该注解时,若该元素是唯一需赋值元素,则无需使用名-值对语法,只需在括号内给出 value 值即可。
编写注解处理器
public class UseCaseTracker {
public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
for(Method m : cl.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if(uc != null) {
System.out.println("Found Use Case:" + uc.id() + " " + uc.description());
useCases.remove(new Integer(uc.id()));
}
}
for(int i : useCases) {
System.out.println("Warning: Missing use case-" + i);
}
}
}
反射方法 getDeclaredMethods()
与 getAnnotation()
均属于 AnnotationElement 接口,Class、Method、Field 均实现了该接口。
getAnnotation()
方法返回指定类型的注解对象。如果没有则返回 null。使用反射获取到注解对象之后,类似使用调用方法的方式获取注解的值,如uc.id()等。
getDeclaredAnnotations()
返回直接存在于此元素上的所有注释。也属于 AnnotationElement 接口。
javac 处理注解
Java SE 6 引入了一个新的功能,叫做 可插入注解处理(Pluggable Annotation Processing) 框架,它提供了标准化的支持来编写自定义的注解处理器。之所以称为“可插入”,是因为注解处理器可以动态插入到 javac 中,并可以对出现在 Java 源文件中的一组注解进行操作。此框架具有两个部分:一个用于声明注解处理器并与其交互的 API 包 javax.annotation.processing
和一个用于对 Java 编程语言进行建模的 API 包 javax.lang.model
。
http://howiefh.github.io/2014/11/06/thinking-in-java-note-7/#javac处理注解
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com
文章标题:《Java编程思想》笔记20-注解
文章字数:1k
本文作者:Bin
发布时间:2018-06-24, 16:48:03
最后更新:2019-08-06, 00:46:42
原始链接:http://coolview.github.io/2018/06/24/Java%E7%BC%96%E7%A8%8B%E6%80%9D%E6%83%B3/%E3%80%8AJava%E7%BC%96%E7%A8%8B%E6%80%9D%E6%83%B3%E3%80%8B%E7%AC%94%E8%AE%B020-%E6%B3%A8%E8%A7%A3/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。