javase注解

一.注解的概念_作用

  1. 例如:@Override(用在子类重写父类的方法),@FunctionInterface(定义函数式接口),@Test(JUnit的,单元测试)。
    注解的作用:写在“源码中”,给“注解解析器”看的。告诉注解解析器,怎样编译、运行后面的代码。
  2. “注解”的本质上就是一个“类”,可以单独定义java文件,编译成class。可以自己单独定义注解。

二.自定义注解的基本格式

  1. 自定义注解:
public @interface MyTest {
    
}
  1. 我们的注解目前有两个问题
    没有任何作用
    注解可以放在任何位置

三.元注解

  1. “元注解”是java内部定义好的注解,专门用在"注解的定义上"
    作用:他可以约束新定义的注解:
    A使用位置;
    b生命周期
    2.示例代码
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
public @interface MyTest {

}
  1. 具体
    A).约束新注解的"使用位置":
    @Target(属性值)
    可选的几个属性值(ElementType枚举):
    ELementType.TYPE:类\接口
    ElementType.FIELD:成员变量
    ElementType.METHOD:成员方法
    ElementType.PARAMENTER:方法参数
    ElementType.CONSTRUCTOR:构造方法
    ElementType.LOCAL_VARIABLE:局部变量
    B).约束新注解的"生命周期":
    @Retention(属性值)
    属性值:可选的几个属性值(RetentionPolicy枚举)
    1 . RetentionPolicy.SOURCE:这个枚举表示注解只存在于源码中,不会被编译到class中.给编译器中的注解解析器用的.@Override
    2 . RetentionPolicy.CLASS:表示此枚举会存在于源码\class文件,但运行时不会被加载到内存.(没有例子)
    3. RetentionPolicy.RUNTIME:这个枚举表示注解会存在源码\class\运行时内存.例如:Junit的@Test注解

解析注解

  1. 模仿Junit
public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //1.获取Student的Class对象
        Class aClass = Class.forName("com.itheima.注解.Student");

        //2.创建对象
        Object o = aClass.getConstructor().newInstance();

        //3.获取Student中所有的公有的方法
        Method[] methods = aClass.getMethods();

        //对方法名进行解析
        Arrays.sort(methods, (o1, o2) -> o1.getName().compareTo(o2.getName()));

        //4.遍历数组
        for (Method m : methods) {
            //5.判断这个Method上是否使用了MyTest注解
            if(m.isAnnotationPresent(MyTest.class)){
                m.invoke(o);
            }
        }
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
public @interface MyTest {

}
@MyTest
public class Student {
    @MyTest
    private int name;

    public Student(){

    }

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

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

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

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

    public int getName() {
        return name;
    }

    public void setName(int name) {
        this.name = name;
    }
}

定义包含属性的注解

  1. 定义格式:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
public @interface MyTest {
    //注解中可以定义属性:格式:属性类型 属性名() [default 值];
    int index() default 0;
}
  1. 使用
@MyTest
public class Student {
    @MyTest
    private int name;

    public Student(){

    }

    @MyTest(index = 3)
    public void show2(){
        System.out.println("show2");
    }

    @MyTest(index = 4)
    public void show1(){
        System.out.println("show1");
    }

    @MyTest(index = 1)
    public void show4(){
        System.out.println("show4");
    }

    @MyTest(index = 2)
    public void show3(){
        System.out.println("show3");
    }

    public int getName() {
        return name;
    }

    public void setName(int name) {
        this.name = name;
    }
}

3.注解解析器(按MyTest注解的index属性值进行排序):

public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //1.获取Student的Class对象
        Class aClass = Class.forName("com.itheima.注解.Student");

        //2.创建对象
        Object o = aClass.getConstructor().newInstance();

        //3.获取Student中所有的公有的方法
        Method[] methods = aClass.getMethods();

        //对方法名进行解析
        Arrays.sort(methods, (o1, o2) -> {
            //按注解的属性index的值,进行排序
            //1.判断两个参数Method是否都是用了MyTest注解
            if (o1.isAnnotationPresent(MyTest.class) && o2.isAnnotationPresent(MyTest.class)) {
                //2.取出每个方法的@MyTest注解对象
                MyTest t1 = o1.getAnnotation(MyTest.class);
                MyTest t2 = o2.getAnnotation(MyTest.class);
                //3.取出每个注解的index属性值
                int index1 = t1.index();
                int index2 = t2.index();
                return index1 - index2;
            }
            return 0;
        });

        //4.遍历数组
        for (Method m : methods) {
            //5.判断这个Method上是否使用了MyTest注解
            if(m.isAnnotationPresent(MyTest.class)){
                m.invoke(o);
            }
        }
    }
}
  1. 其他一些问题:
    1).注解的属性的数据类型:四类八种的基本数据类型\class类型\String类型\注解类型\枚举类型\以上几种的数组类型.
    2).如果"注解"中只有一个属性.而且属性名叫:value,使用注解时,可以省略"属性名",直接设置值.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
public @interface MyTest {
    //注解中可以定义属性:格式:属性类型 属性名() [default 值];
    int value() default 0;
}
@MyTest
public class Student {
    @MyTest
    private int name;

    public Student() {

    }

    @MyTest(value = 3)
    public void show2() {
        System.out.println("show2");
    }

    @MyTest(value = 4)
    public void show1() {

        System.out.println("show1");
    }

    @MyTest(1)
    public void show4() {
        System.out.println("show4");
    }

    @MyTest(2)
    public void show3() {
        System.out.println("show3");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值