注解和反射

来源:互联网 发布:淘宝网商城玩具店 编辑:程序博客网 时间:2024/04/26 11:35
1、JDK中提供的三个基本的注解@Deprecated:标注XX过时的。@SuppressWarnings:抑制警告    unused:抑制的警告类型    { "unused", "rawtypes", "unchecked" }:数组,抑制的多个警告类型    all:抑制所有警告@Override:保证用户确实是覆盖了父类的某个方法。2、自定义注解使用@interface关键字来声明注解:public @interface MyAnn1{}声明注解的属性字段:类型 字段名() [defalut 默认值];注解属性的类型只能下面的几种:String Class 八个基本类型 注解类型 枚举类型 及以上类型的1维数组。特殊属性:String value;或String[] value();使用时,直接给定取值,而不用加属性名称
//定义注解public @interface MyAnn1 {    String name() default "";    int age() default -1;    String city();    MyAnn2[] ann(); //注解中使用注解类型}public @interface MyAnn2 {    String name() default "";    String[] value() default ""; //使用是直接使用即可,不需要写属性名}
public class UserMyAnn1 {    // @MyAnn1(name="wf",age=98,city="山沟沟")//没有指定属性    // public void m1(){    //    // }    @MyAnn2("abc")    // 如果省略属性名,就是给value赋值    public void m2() {    }    @MyAnn2(value = "abc", name = "def")    public void m3() {    }    //数组形式    @MyAnn2(name = "def", value = { "a", "b", "c" })    public void m4() {    }//注解中使用注解类型    @MyAnn1(name = "abc", city = "BJ", ann = {            @MyAnn2(name = "a", value = "b"), @MyAnn2(name = "c", value = "d") })    public void m5() {    }}
3、元注解服务于注解的注解就是元注解*@Retention:指定注解的存活范围。默认是CLASSRetentionPolicy:SOURCE|CLASS|RUNTIME

这里写图片描述

*@Target:指定注解可以用在什么元素上ElementType:TYPE|METHOD|。。。@Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.@Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解
//注解和反射一起使用:public class MyJunitTest {    @MyTest(time=100000000)    public void testAdd(){        System.out.println("执行了add方法的测试");    }    @MyTest    public void testUpdate(){        System.out.println("执行了update方法的测试");    }}//反射实现单元测试://反射注解:所有注解类型都是Annotation类型的子类/*java.lang.reflect.AnnotatedElement:    <T extends Annotation> getAnnotation(Class<T> annotationType):        获取指定类型的注解    Annotation[] getAnnotations():获取所有的注解    Annotation[] getDeclareAnnotations():返回直接存在于此元素上的所有注释,包含继承    boolean isAnnotationPresend(Class<? extends Annotation>):有木有指定的注解    Class, Constructor, Field, Method, Package都实现了该接口 */public class MyTestRunner {    //执行测试:    /*     * 获取要测试的java类:MyJunitTest     * 取到其中的所有方法:Method     * 看看谁的方法前面有@MyTest的注解,谁有就执行谁     */    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {        test2();    }    //反射带有属性的注解    private static void test2() throws IllegalAccessException,            InvocationTargetException, InstantiationException {        Class clazz = MyJunitTest.class; //获取要测试的类        Method ms[] = clazz.getMethods();        for(Method m:ms){            MyTest myTest = m.getAnnotation(MyTest.class); //从方法上获取指定类型的注解  @MyTest            if(myTest!=null){                //得到注解的属性                long timeLimit = myTest.time(); //获取指定类型的注解的属性上面的值 @MyTest(time=100000000)                if(timeLimit>-1){                    //有性能测试需求                    long startTime = System.nanoTime();                    m.invoke(clazz.newInstance(), null); //执行每个方法                    long useTime = System.nanoTime()-startTime;                    if(useTime>timeLimit){                        System.out.println(m.getName()+"执行效率没有测试通过");                    }                }else{                    //没有性能测试需求                    m.invoke(clazz.newInstance(), null);                }            }        }    }    //注解的基本反射    private static void test1() throws IllegalAccessException,            InvocationTargetException, InstantiationException {        Class clazz = MyJunitTest.class;        Method ms[] = clazz.getMethods();        for(Method m:ms){            boolean b = m.isAnnotationPresent(MyTest.class); //判断有木有指定的注解//          System.out.println(m.getName()+"方法上有木有MyTest注解:"+b);            if(b){                m.invoke(clazz.newInstance(), null);//            }        }    }}
0 0
原创粉丝点击