Java 自定义注解及利用反射读取注解
一、自定义注解
元注解:
@interface 注解: 定义注解接口
@Target 注解: 用于约束被描述的注解的使用范围,当被描述的注解超出使用范围则编译失败。如:ElementType.METHOD,ElementType.TYPE;
@Retention 注解:用于约束被定义注解的作用范围,作用范围有三个:
1,、RetentionPolicy.SOURCE: 作用范围是源码,作用于 Java 文件中,当执行 javac 时去除该注解。
2、RetentionPolicy.CLASS:作用范围是二进制码,就是存在于 class 文件中,当执行 Java 时去除该注解。
3、RetentionPolicy.RUNTIME:作用范围为运行时,就是我们可以通过动态获取该注释。
@Documented:用于指定 javadoc 生成 API 文档时显示该注释。
@Inherited: 用于指定被描述的注释可以被其描述的类的子类继承,默认情况是不能被其子类继承。
自定义注解接口:
1 package com.java.annotation; 2 3 import java.lang.annotation.Documented; 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Inherited; 6 import java.lang.annotation.Retention; 7 import java.lang.annotation.RetentionPolicy; 8 import java.lang.annotation.Target; 9 10 @Target({ElementType.METHOD,ElementType.TYPE}) 11 @Inherited 12 @Documented 13 @Retention(RetentionPolicy.RUNTIME) 14 public @interface Annotation_my { 15 16 String name() default "张三";//defalt 表示默认值 17 18 String say() default "hello world"; 19 20 int age() default 21; 21 22 }
接下来我们定义一个接口:
package com.java.annotation;@Annotation_my //使用我们刚才定义的注解
public interface Person {@Annotation_my </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> name(); @Annotation_my </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> say(); @Annotation_my </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> age();
}
接口定义好了,我们就可以写接口的实现类了(接口不能实例化)
package com.java.annotation;@Annotation_my
@SuppressWarnings("unused")
public class Student implements Person {</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> String name; @Override @Annotation_my(name</span>="流氓公子") <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">赋值给name 默认的为张三
//在定义注解时没有给定默认值时,在此处必须 name 赋初值
public void name() {} @Override @Annotation_my(say</span>=" hello world !"<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> say() { } @Override @Annotation_my(age</span>=20<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> age() { }
}
然后我们就编写一个测试类测试我们的注解
package com.java.annotation;import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class Text {
Annotation[] annotation = null;</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> main(String[] args) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> ClassNotFoundException { </span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Text().getAnnotation(); } </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> getAnnotation() <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> ClassNotFoundException{ Class</span><?> stu = Class.forName("com.java.annotation.Student"<span style="color: rgba(0, 0, 0, 1)">);//静态加载类 </span><span style="color: rgba(0, 0, 255, 1)">boolean</span> isEmpty = stu.isAnnotationPresent(com.java.annotation.Annotation_my.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);//判断stu是不是使用了我们刚才定义的注解接口</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(isEmpty){ annotation </span>=<span style="color: rgba(0, 0, 0, 1)"> stu.getAnnotations();//获取注解接口中的 </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">(Annotation a:annotation){ Annotation_my my </span>=<span style="color: rgba(0, 0, 0, 1)"> (Annotation_my)a;//强制转换成Annotation_my类型 System.out.println(stu</span>+":\n"+my.name()+" say: "+my.say()+" my age: "+<span style="color: rgba(0, 0, 0, 1)">my.age()); } } Method[] method </span>=<span style="color: rgba(0, 0, 0, 1)"> stu.getMethods();// System.out.println(</span>"Method"<span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">(Method m:method){ </span><span style="color: rgba(0, 0, 255, 1)">boolean</span> ismEmpty = m.isAnnotationPresent(com.java.annotation.Annotation_my.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">); </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(ismEmpty){ Annotation[] aa </span>=<span style="color: rgba(0, 0, 0, 1)"> m.getAnnotations(); </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">(Annotation a:aa){ Annotation_my an </span>=<span style="color: rgba(0, 0, 0, 1)"> (Annotation_my)a; System.out.println(m</span>+":\n"+an.name()+" say: "+an.say()+" my age: "+<span style="color: rgba(0, 0, 0, 1)">an.age()); } } } </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">get Fields by force</span> System.out.println("get Fileds by force !"<span style="color: rgba(0, 0, 0, 1)">); Field[] field </span>=<span style="color: rgba(0, 0, 0, 1)"> stu.getDeclaredFields(); </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">(Field f:field){ f.setAccessible(</span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">); System.out.println(f.getName()); } System.out.println(</span>"get methods in interfaces !"<span style="color: rgba(0, 0, 0, 1)">); Class</span><?> interfaces[] =<span style="color: rgba(0, 0, 0, 1)"> stu.getInterfaces(); </span><span style="color: rgba(0, 0, 255, 1)">for</span>(Class<?><span style="color: rgba(0, 0, 0, 1)"> c:interfaces){ Method[] imethod </span>=<span style="color: rgba(0, 0, 0, 1)"> c.getMethods(); </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)">(Method m:imethod){ System.out.println(m.getName()); } } }
}