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>&lt;?&gt; 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>&lt;?&gt; interfaces[] =<span style="color: rgba(0, 0, 0, 1)"> stu.getInterfaces();
    </span><span style="color: rgba(0, 0, 255, 1)">for</span>(Class&lt;?&gt;<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());
        }
    }
}

}