注解(Annotation) --java学习笔记

注解

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

自定义注解

就是自己定义注解

自定义注解到底该怎么写:

public @interface MyTest1 {
    String aaa();
    boolean bbb() default true;
    String[] ccc();
}

自定义注解写了属性,在使用注解时,除非该属性设置了默认值,不然一定要给属性赋值

特殊属性名:value

  • 如果注解中只有一个value属性,使用注解时,value名称可以不写!!
public @interface MyTest2 {
    String value(); //特殊属性
}

注解可以用在类、方法、变量等:

package com.zeyu.annotation;
@MyTest1(aaa="zeYu",ccc={"aaa","bbb","ccc"})
//@MyTest2(value="zeYu")
@MyTest2("zeYu")    //注解中只有一个value属性,使用注解时,value名称可以不写
public class annotationTest1 {
    @MyTest1(aaa="zeYu",bbb=false,ccc={"ddd","eee"})
    public void test1(){

    }
}

注解的原理

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

元注解

  • 指的是:修饰注解的注解

例如:

常用元注解:

代码演示:

package com.zeyu.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE,ElementType.METHOD})   //ElementType.TYPE表示该注解只可以用在类和方法上
@Retention(RetentionPolicy.RUNTIME) //控制下面的注解一直保留到运行时
public @interface MyTest3 {

}

测试:

package com.zeyu.annotation;
@MyTest3    //用在类上没问题
public class annotationTest2 {
//    @MyTest3    //用在成员变量不行
    public String name;

    @MyTest3    //用在方法上没问题
    public void test(){

    }
}

什么是注解的解析?

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

如何解析注解?

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

解析注解的案例

具体需求如下:

  1. 定义注解MyTest4,要求如下
    包含属性:String value()
    包含属性:double aaa(),默认值为 100
    包含属性:Stringll bbb()
    限制注解使用的位置:类和成员方法上
    指定注解的有效范围:一直到运行时
  2. 定义一个类叫:Demo,在类中定义一个test1方法,并在该类和其方法上使用MyTest4注解
  3. 定义AnnotationTest3测试类,解析Demo类中的全部注解

代码:

MyTest4:
package com.zeyu.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {
    String value();
    double aaa() default 100;
    String[] bbb();
}
Demo:
package com.zeyu.annotation;
@MyTest4(value="zeYu",bbb={"aaa","bbb"})
public class Demo {
    @MyTest4(value="zeYu",bbb={"ccc","ddd"})
    public void test1(){

    }
}
annotationTest3:
package com.zeyu.annotation;

import org.junit.Test;

import java.lang.reflect.Method;
import java.util.Arrays;

public class annotationTest3 {
    @Test
    public void parseClass(){
        //先得到Class对象
        Class c = Demo.class;
        //判断类上是否包含了某个注解
        if(c.isAnnotationPresent(MyTest4.class)){
            MyTest4 myTest4 = (MyTest4) c.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 Exception {
        //先得到Class对象
        Class c = Demo.class;
        Method test1 = c.getDeclaredMethod("test1");

        //判断类上是否包含了某个注解
        if(test1.isAnnotationPresent(MyTest4.class)){
            MyTest4 myTest4 = (MyTest4) test1.getDeclaredAnnotation(MyTest4.class);
            System.out.println(myTest4.value());
            System.out.println(myTest4.aaa());
            System.out.println(Arrays.toString(myTest4.bbb()));
        }
    }
}

测试结果:

案例:模拟Junit框架

需求

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

分析

  1. 定义一个自定义注解MyTest,只能注解方法,存活范围是一直都在
  2. 定义若干个方法,部分方法加上@MyTest注解修饰,部分方法不加
  3. 模拟一个junit程序,可以触发加了@MyTest注解的方法执行

代码:

MyTest:
package com.zeyu.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) //只能用在方法上
@Retention(RetentionPolicy.RUNTIME) //一直到运行时都存在
public @interface MyTest {
}

测试类:

package com.zeyu.annotation;

import java.lang.reflect.Method;

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 Exception {
        //1、得到Class对象
        Class c = annotationTest4.class;
        annotationTest4 a = new annotationTest4();
        //2、提取这个类中的全部成员方法
        Method[] methods = c.getDeclaredMethods();
        //3、遍历这个数组中的每个方法,看方法上是否存在@MyTest注解,存在则执行该方法
        for (Method method : methods) {
            if (method.isAnnotationPresent(MyTest.class)) {
                //说明存在该注解,执行该方法
                method.invoke(a);
            }
        }
    }
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

A泽予

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

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

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

打赏作者

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

抵扣说明:

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

余额充值