Java基础-注解


※ 学习目标

  • 什么是注解?
  • 注解的作用是啥?
  • 如何自定义注解?
  • 元注解是什么?各自的作用是什么?
  • 什么是注解的解析?注解解析的步骤是啥?

一、什么是注解

就是Java代码里的特殊标记,比如:@Override,@Test等
作用是:让其他程序根据注解信息来解决怎么执行该程序。
注意:注解可以用在类、构造器、方法、成员变量、参数等位置

二、自定义注解

自定义注解的格式

public @interface 注解名称{
	public 属性类型 属性名() default 默认值;
}

特殊属性名:value

如果注解中只有一个value属性,使用注解时,value名称可以不写!

三、注解原理

  • 注解本质是一个接口,Java中所有注解都是继承了Annotation接口的。
  • @注解(…):其实就是一个实现类对象,实现了改注解以及Annotation接口

四、元注解

修饰注解的注解

4.1 @Target

作用:声明被修饰的注解只能在哪些位置使用

在这里插入图片描述

@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyTest3 {
}

4.2 @Retention

作用:声明注解的保留周期

在这里插入图片描述

// 一般使用 RetentionPolicy.RUNTIME 
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest3 {
}

五、注解的解析

判断类、方法、成员变量上是否存在注解,并把注解的内容解析出来

如何解析注解?

  1. 指导思想:要解析谁上面的注解,就应该先拿到谁。
  2. 要解析类上面的注解,应该先获取该类的Class对象,再通过Class对象解析其上面的注解
  3. 要解析成员方法上的注解,应该先获取成员方法的Method对象,再通过Method对象解析上面的注解
  4. Class、Method、Field、Constructor,都实现了AnnotatedElement接口,都拥有解析注解的能力

API

方法说明
public Annotation[] getDeclaredAnnotations()获取当前对象上面的注解
public T getDeclaredAnnotation(Class annotationClass)获取指定的注解对象
public boolean isAnnotationPresent(Class annotationClass)判断当前对象上是否存在某个注解
/**
 * 目标:掌握注解解析
 * <p>
 * 1. 定义注解 @MyTest4
 * 属性:String value()
 * double aaa() 默认值 100
 * String[] bbb()
 * 限制注解的位置:类和方法上
 * 限制注解的有效范围:一直到运行时
 * 2. 当以一个类:Demo,在类中定义一个test1方法,并在该类和其方法上使用 @MyTest4 注解
 * 3. 定义 AnnotationTest3测试类,解析Demo类中的全部注解
 */
public class AnnotationTest3 {
    @Test
    public void parseClass() {
        // 1. 得到Class对象
        Class demoClass = Demo.class;

        // 2. 获取当前对象的所有注解
        Annotation[] annotations = demoClass.getDeclaredAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        System.out.println("---------------------------------------------------");

        // 4. 判断当前对象上是否存在某个注解
        boolean present = demoClass.isAnnotationPresent(MyTest4.class);
        if (present) {
            // 3. 获取指定的注解对象
            MyTest4 myTest4 = (MyTest4) demoClass.getDeclaredAnnotation(MyTest4.class);
            System.out.println(myTest4.value());
            System.out.println(myTest4.aaa());
            System.out.println(Arrays.toString(myTest4.bbb()));
        }
    }

    @Test
    public void parseMethod() throws NoSuchMethodException {
        // 1. 得到Class对象
        Class demoClass = Demo.class;

        // 2. 获取方法
        Method method = demoClass.getDeclaredMethod("test1");

        // 2. 获取当前对象的所有注解
        Annotation[] annotations = method.getDeclaredAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        System.out.println("---------------------------------------------------");

        // 4. 判断当前对象上是否存在某个注解
        boolean present = method.isAnnotationPresent(MyTest4.class);
        if (present) {
            // 3. 获取指定的注解对象
            MyTest4 myTest4 = (MyTest4) method.getDeclaredAnnotation(MyTest4.class);
            System.out.println(myTest4.value());
            System.out.println(myTest4.aaa());
            System.out.println(Arrays.toString(myTest4.bbb()));
        }
    }
}
@MyTest4(value = "蜘蛛精", aaa = 999.5, bbb = {"至尊宝", "牛魔王"})
public class Demo {
    @MyTest4(value = "孙悟空", aaa = 1999.5, bbb = {"紫霞", "刘夫人"})
    public void test1() {

    }
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {
    String value();

    double aaa() default 100;

    String[] bbb();
}

六、应用场景

定义若干方法,只要加了 MyTest 注解,就会触发该方法的执行。

  1. 定义一个自定义注解 MyTest ,只能注解方法,存活范围是一直都在。
  2. 定义若干方法,部分方法加上 @MyTest 注解修饰,部分方法不加。
  3. 模拟一个junit程序,可以触发加了 @MyTest 注解的方法执行。
public class AnnotationTest4 {
    @MyTest
    public void test1() {
        System.out.println("------------ test1 ------------");
    }

    // @MyTest
    public void test2() {
        System.out.println("------------ test2 ------------");
    }

     @MyTest
    public void test3() {
        System.out.println("------------ test3 ------------");
    }

    @MyTest
    public void test4() {
        System.out.println("------------ test4 ------------");
    }

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        AnnotationTest4 annotationTest4 = new AnnotationTest4();

        Class aClass = AnnotationTest4.class;

        Method[] methods = aClass.getDeclaredMethods();

        for (Method method : methods) {
            if (method.isAnnotationPresent(MyTest.class)) {
                method.invoke(annotationTest4);
            }
        }
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Monly21

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值