版权声明:本文为博主原创文章,转载请标明地址。欢迎关注微信订阅号:PM实验室。 https://blog.csdn.net/plain_maple/article/details/56923087
目录:
解析注解
测试注解生命周期
测试注解的继承性
解析注解
概括的讲,就是通过反射获取类或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
1、自定义注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnno {
String value();
}
2、定义 Person 接口
public interface Person {
public String name();
public int age();
@Deprecated
public void fight();
}
3、实现 Person 接口的 Student 类,并且使用了刚刚自定义的 MyAnno 注解。
@MyAnno("这是在 Student 类上的注解")
public class Student implements Person {
@Override
@MyAnno("这是在 name 方法上的注解")
public String name() {
return null;
}
@Override
public int age() {
return 0;
}
@Override
public void fight() {
}
}
4、测试类: 解析类上的注解
public static void main(String[] args) {
try {
//1、使用类加载器加载类。
Class mClass = Class.forName("com.guofeng.Student");
//2、找到此类上面的注解。此方法判断加载的类上是否存在 MyAnno 这个注解。
boolean isExist = mClass.isAnnotationPresent(MyAnno.class);
if (isExist) {
//3、得到注解实例。
MyAnno myAnno = (MyAnno) mClass.getAnnotation(MyAnno.class);
System.out.println(myAnno.value());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
输出:
这是在 Student 类上的注解
5、解析方法上的注解
测试类增加下面代码:
//4、找到方法上的注解
//获取类中方法
Method[] ms = mClass.getMethods();
//遍历方法
for (Method m : ms) {
boolean isMethodExist = m.isAnnotationPresent(MyAnno.class);
if (isMethodExist) {
MyAnno myAnno = (MyAnno) m.getAnnotation(MyAnno.class);
System.out.println(myAnno.value());
}
}
输出:
这是在 Student 类上的注解
这是在 name 方法上的注解
6、第二种方式获取方法上的注解
//5、测试类增加下面代码
for (Method m : ms) {
//获取每个方法的全部注解
Annotation[] annotation = m.getAnnotations();
for (Annotation a : annotation) {
if (a instanceof MyAnno) {
MyAnno myAnno = (MyAnno) a;
System.out.println(myAnno.value());
}
}
}
测试注解的生命周期
我们将自定义注解的生命周期改为 SOURCE。
@Retention(RetentionPolicy.SOURCE)
然后编译运行,发现什么也没有打印出来。
因为标注上 SOURCE 意味着注解只存在于源码状态,成为 .Class文件后就不起作用了。
再改成:
@Retention(RetentionPolicy.CLASS)
还是什么也没有打印出来,因为我们动态加载类,只能取到运行时的注解。
测试注解的继承性
1、将 Student 和 Person 类从实现接口关系修改成继承关系。
父类在类和方法上增加注解:
@MyAnno("Person interface,annotation")
public class Person {
@MyAnno("Person interface,name method,annotation")
public String name(){
return null;
}
public int age(){
return 0;
}
@Deprecated
public void fight(){
}
}
删除子类的注解:
public class Student extends Person {
@Override
public String name() {
return null;
}
@Override
public int age() {
return 0;
}
@Override
public void fight() {
}
}
运行代码,打印如下:
Person interface,annotation
从而可以看出只继承了 Person 类上的注解。