一、概述
(一)注解的概述
- Java 注解(Annotation)又称Java标注,是JDK5引入的注释机制。
- Java 语言中的类、构造器、方法、成员变量、参数等都可以以注解的形式标注。
(二)注解的作用
- 对Java中类、方法、变量做标记,然后进行特殊处理。
二、自定义注解
(一)自定义注解格式
public @interface 注解名称 {public 属性类型 属性名() default 默认值;
}
(二)自定义注解示例
public @interface MyBook {String id();String[] names();double price();//特殊的属性value,当只定义一个属性且名称为value则调用时可不写value,若有多个,则必须填写String value();
}
三、元注解
(一)概念: 元注解是以注解的形式作用在注解中的一种注解形式。
(二)常见元注解
- @Target——约束自定义注解的使用范围
- @Retention——声明注解的生命周期
(三)常见元注解参数的常用值
@Target——ElementType枚举类
值 | 作用域 |
---|---|
TYPE | 类/接口 |
FIELD | 成员变量 |
METHOD | 成员方法 |
PARAMETER | 方法参数 |
CONSTRUCTOR | 构造器 |
LOCAL_VARIABLE | 局部变量 |
@Retention——RententionPolicy枚举类
值 | 作用域 |
---|---|
SOURCE | 作用于源码阶段,生成的字节码文件不存在 |
CLASS | 作用于源码阶段,字节码文件阶段,运行阶段不存在,默认值 |
RUNTIME | 作用于源码阶段,字节码文件阶段,运行阶段,开发常用 |
(四)使用元注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Book{String value();
}
四、注解解析
(一)概念: 注解解析是判断注解是否存在并解析其内容。
(二)相关API
- Annotation接口:注解的原始接口
- AnnotationElement:定义了注解解析方法
方法 | 说明 |
---|---|
Annotation[] getDeclaredAnnotations() | 获取当前对象上使用的所有注解,返回注解数组 |
T getDeclaredAnnotation(Class<T> annotationClass) | 根据注解类型获得对应注解对象 |
boolean isAnnotationPresent(Class<Annotation> annotationClass) | 判断对象是否使用了指定接口 |
(三)解析注解的技巧: 注解在哪个成分上,先解析哪个成分对象
(四)解析案例
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Book{String value(); //书名double price() default 100; //价格 默认为100String[] authors(); //多位作者
}@Book(value = "《Java深度学习》",price = 100,authors = {"xxx","xxx","xxx"})
class BookStore{private String name;private double price;private String[] authors;@Book(value = "《Java浅度学习》",price = 50,authors = {"佚名"})public void text(){}@Overridepublic String toString() {return "BookStore{" +"name='" + name + '\'' +", price=" + price +", authors=" + Arrays.toString(authors) +'}';}
}public class AnnotationDemo{@Testpublic void parseClass(){//1、先得到类对象Class c = BookStore.class;//2、判断是否存在if (c.isAnnotationPresent(Book.class)){//3、直接获取注解对象Book annotation = (Book) c.getDeclaredAnnotation(Book.class);System.out.println(annotation.value());System.out.println(annotation.price());System.out.println(Arrays.toString(annotation.authors()));}}@Testpublic void parseMethod() throws NoSuchMethodException {//1、先得到类对象Method c = BookStore.class.getMethod("text");//2、判断是否存在if (c.isAnnotationPresent(Book.class)){//3、直接获取注解对象Book annotation = (Book) c.getDeclaredAnnotation(Book.class);System.out.println(annotation.value());System.out.println(annotation.price());System.out.println(Arrays.toString(annotation.authors()));}}
}/*测试结果*/
《Java深度学习》
100.0
[xxx, xxx, xxx]
======================
《Java浅度学习》
50.0
[佚名]
五、注解的应用——模拟Junit测试框架
/*
* 需求:定义若干个方法,只要加了MyTest注解,就可以触发执行
* 分析:获取类中成员方法,判断是否有注解,若有注解则执行,否则不执行
*/public class JunitDemo {@MyJunitpublic static void test1(){System.out.println("=======test1========");}public static void test2(){System.out.println("=======test2========");}@MyJunitpublic static void test3(){System.out.println("=======test3========");}public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {Class anno = JunitDemo.class;Method[] methods = anno.getMethods();for (Method method :methods) {if (method.isAnnotationPresent(MyJunit.class)){method.invoke(anno);}else System.out.println(method.getName() + "未执行");}}}@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyJunit{}