系统:Win10
Java:1.8.0_333
IDEA:2020.3.4
Gitee:https://gitee.com/lijinjiang01/JavaWeb
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制
Java 语言中的类、构造器、方法、成员变量、参数等都可以被注解进行标注
对 Java 中类、方法、成员变量做标记,然后进行特殊处理,至于到底做何种处理由业务需求来决定
例如:JUnit 框架中,标记了注解 @Test 的方法就可以被当成测试方法执行,而没有标记的就不能当成测试方法执行
自定义注解就是自己做一个注解来使用
特殊属性:
value 属性:如果只有一个 value 属性的情况下,使用 value 属性的时候可以省略 value 名称不写
但是如果由多个属性,且多个属性没有默认值,那么 value 名称是不能省略的
首先写一个注解类 MyBook
public @interface MyBook {
String name();
String[] authors();
double price();
}
再写一个测试类
@MyBook(name = "《水浒传》", authors = {"施耐庵"}, price = 46.0)
public class AnnotationDemo01 {
@MyBook(name = "《三国演义》", authors = {"罗贯中"}, price = 36.0)
private String name;
@MyBook(name = "《西游记》", authors = {"吴承恩"}, price = 40.0)
public AnnotationDemo01() {
}
@MyBook(name = "《红楼梦》", authors = {"曹雪芹"}, price = 46.0)
public static void main(String[] args) {
@MyBook(name = "《山海经》", authors = {"徐客"}, price = 43.6)
int index = 1;
}
}
元注解:就是注解注解的注解
常用元注解:
@Target:约束自定义注解的标记范围
@Retention:申明注解的生命周期
@Target 中可使用的值定义在 ElementType 枚举类中,常用如下
值 | 说明 |
---|---|
CONSTRUCTOR | 构造器 |
FIELD | 成员变量 |
LOCAL_VARIABLE | 局部变量 |
METHOD | 成员方法 |
PARAMETER | 方法参数 |
TYPE | 类、接口 |
@Retention 中可使用的值定义在 RetentionPolicy 枚举类中,常用值如下:
值 | 说明 |
---|---|
SOURCE | 注解将被编译器丢弃 |
CLASS | 注解作用在源码阶段,字节码文件阶段,但不需要在运行时保留,默认值 |
RUNTIME | 注解作用在源码阶段,字节码文件阶段,运行阶段(开发常用) |
注解的操作中经常需要进行解析,注解的解析就是判断是否存在注解,存在注解就解析出内容
与注解解析相关的接口:
Annotation:注解的顶级接口,注解都是 Annotation 类型的对象
AnnotatedElement:该接口定义了与注解解析相关的解析方法
方法 | 说明 |
---|---|
Annotation[] getDeclaredAnnotations() | 获得当前对象上使用的所有注解,返回注解数组 |
T getDeclaredAnnotation(Class annotationClass) | 根据注解类型获得对应注解对象 |
boolean isAnnotationPresent(Class annotationClass) | 判断当前对象是否使用了指定的注解,如果使用了则返回 true,否则 false |
需求:
首先创建 Book 注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Book {
String value();
double price() default 100;
String[] authors();
}
定义使用类 BookStore
@Book(value = "《山海经》", price = 43.6, authors = {"徐客"})
public class BookStore {
@Book(value = "《西游记》", price = 40.0, authors = {"吴承恩"})
public void getBook() {
}
}
定义测试类 AnnotationDemo
import java.lang.reflect.Method;
import java.util.Arrays;
public class AnnotationDemo {
public static void main(String[] args) {
// 1.获取class对象
Class c = BookStore.class;
// 2.判断是否有Book注解
if (c.isAnnotationPresent(Book.class)){
Book book = (Book) c.getDeclaredAnnotation(Book.class);
System.out.println("========================");
System.out.print(book.value());
System.out.print(book.price());
System.out.println(Arrays.toString(book.authors()));
}
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
Book book = (Book) method.getDeclaredAnnotation(Book.class);
System.out.println("========================");
System.out.print(book.value());
System.out.print(book.price());
System.out.println(Arrays.toString(book.authors()));
}
}
}
需求:定义若干个方法,只有加了 MyTest 注解,才可以在启动时被触发运行
分析:
首先定义 MyTest 注解类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyTest {
}
然后创建方法类 AnnotationDemo
public class AnnotationDemo {
@MyTest
public void method01(){
System.out.println("运行方法method01");
}
@MyTest
public void method02(){
System.out.println("运行方法method02");
}
public void method03(){
System.out.println("运行方法method03");
}
@MyTest
public void method04(){
System.out.println("运行方法method04");
}
}
最后创建运行方法类 RunMethod
import java.lang.reflect.Method;
public class RunMethod {
public static void main(String[] args) throws Exception {
AnnotationDemo demo = new AnnotationDemo();
// 1.获取class对象
Class c = AnnotationDemo.class;
// 2.获取所有方法
Method[] methods = c.getDeclaredMethods();
// 3.遍历
for (Method method : methods) {
// 4.判断是否有MyTest注解
if (method.isAnnotationPresent(MyTest.class)){
method.invoke(demo);
}
}
}
}