注解二——注解的使用

上一篇我们简单说了一下注解的入门,本篇我们了解一下注解的使用——自定义注解

我们首先定义一个简单的注解,只需要使用@interface 关键字来标识一下,他就成为了一个Person注解,这个注解的生命周期是到字节码阶段,使用范围是使用在类上面或者方法上面。

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Person {
}

在Annotation的实现中就看到了@Person注解,再一次印证所有注解都是基于Annotation实现

我们再写一个类,这个没有什么内容,只有一个@Person注解

@Person
public class PersonTest {
}

最后在写一个测试入口类

public class AnnotationTest {
    public static void main(String[] args) throws  Exception {
        //通过反射获取到PersonTest的字节码类
        Class  clazz = Class.forName("com.lp.PersonTest");
        //通过PersonTest的字节码类获取这个类上面的所有注解
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            //便利注解打印出注解的类型
            Class<? extends Annotation> annotationType = annotation.annotationType();
            System.out.println(annotationType);
        }
    }
}

我们运行这个测试类,发现什么都没有打印出来,按照我们的预期应该打印出一个@Person才对呀,那么问题出现在什么地方呢。。。其实我们定义@Person注解的时候指定了它的什么周期是到字节码的时候,当字节码加载到内存时这个注解就消失了,日然就打印不出来,那么我们把@Person 的生命周期指定到RUNTIME,再来测试一下,

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Person {
}

打印结果如下, 通过annotationType方法我们获取了注解类型,这里主要强调两点,一个是注解的生命周期,再一个就是可以通过反射获取一个类的所有注解

下面我们给@Person注解加上两个属性,name和age

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Person {
    String name();
    int age();
}

 加上一个我们再看,PersonTest直接报错,因为没有给它的属性赋值

那么我们也可以给它指定默认值

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Person {
    String name() default "小李";
    int age() default 8;
}

或者给它赋值以后就不报错了 

@Person(name = "小明",age=10)
public class PersonTest {
}

下面我们通过测试类来获取它的属性,

public class AnnotationTest {
    public static void main(String[] args) throws  Exception {
        //通过反射获取到PersonTest的字节码类
        Class  clazz = Class.forName("com.lp.PersonTest");
        //通过PersonTest的字节码类获取这个类上面的所有注解
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            //遍历注解打印出注解的类型
            Class<? extends Annotation> annotationType = annotation.annotationType();
            //检验PersonTest上面的注解是否有Person注解
            if (clazz.isAnnotationPresent(Person.class)){
                //如果有,获取Person注解
                Person personAnnotation = (Person) clazz.getAnnotation(Person.class);
                //打印出属性
                System.out.println("personAnnotation:"+personAnnotation.name()+"---"+personAnnotation.age());
            }
            System.out.println("annotationType:"+annotationType);
        }
    }
}

运行结果

注解属性类型可以是八个基本类型,String类型,Class类型,enum枚举类型,注解类型,前面这些类型的数组类型

下面我们把这些类型的属性都加上来获取它的属性值

public enum GradeEnum {
    FirstGrade,SecondGrade,ThirdGrade
}
public @interface MetaAnnotation {
    String value();
}

这个地方说一句,当一个注解中只有一个value属性时当使用的时候传参是可以不指定属性名称的,例如

MetaAnnotation annotation() default @MetaAnnotation("lp");就可以直接传参

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Person {
    String name() default "小李";
    int age() default 8;
    String[] pencilColor() default {"blue","red","yellow"};
    GradeEnum grade() default GradeEnum.FirstGrade;
    MetaAnnotation annotation() default @MetaAnnotation("lp");
    Class clazz() default Person.class;
}
public class AnnotationTest {
    public static void main(String[] args) throws  Exception {
        //通过反射获取到PersonTest的字节码类
        Class  clazz = Class.forName("com.lp.PersonTest");
        //通过PersonTest的字节码类获取这个类上面的所有注解
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            //遍历注解打印出注解的类型
            Class<? extends Annotation> annotationType = annotation.annotationType();
            //检验PersonTest上面的注解是否有Person注解
            if (clazz.isAnnotationPresent(Person.class)){
                //如果有,获取Person注解
                Person personAnnotation = (Person) clazz.getAnnotation(Person.class);
                //打印出属性
                System.out.println("personAnnotation:"+personAnnotation.name()+
                        "---"+personAnnotation.age()+
                        "---"+personAnnotation.annotation().value()+
                        "---"+personAnnotation.clazz()+
                        "---"+personAnnotation.grade().name()+
                        "---"+personAnnotation.pencilColor().length
                );
            }
            System.out.println("annotationType:"+annotationType);
        }
    }
}

我们可以看到都可以获取出来,注解的基本定义就说到这里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值