java反射与注解的简单使用

项目开发中boss要求使用反射和注解,当时是有点懵的,毕竟是个Android开发,java功底不深厚.在此记录一下学习历程.

声明两个注解:
用于类中的属性变量

@Target(FIELD)
@Retention(RUNTIME)
public @interface FieldUrl {
//这里默认值赋为空字符串
    String value() default "";
}

用于类中的方法:

@Target(METHOD)
@Retention(RUNTIME)
public @interface MethodUrl {
    String value() default "";
}

创建一个测试类Test :

public class Test {
    @FieldUrl("1")
    public String one;

    @FieldUrl("2")
    public String two;

    @MethodUrl("1")
    public void methodOne(){
        if(one!=null){
            Log.i("urlTest=====","methodOne11111=="+one);
        }
    }

    @MethodUrl("2")
    public void methodTwo(String oTwo){
        if(two!=null){
            Log.i("urlTest=====","methodTwo11111=="+two);
        }
        if(oTwo!=null){
            Log.i("urlTest=====","methodTwo22222=="+oTwo);
        }
    }
}

下面进入主题,使用方法:

private void getTestClass() throws InstantiationException, IllegalAccessException {
        Class c = Test.class;
        Test  t = (Test) c.newInstance();
        Field[] fs = c.getDeclaredFields();//获取类中属性
        Log.i("urlTest=====","Field.size=="+fs.length);
        for(Field field : fs){
//            Log.i("urlTest=====","Field.name=="+field.getName());
            FieldUrl fu = field.getAnnotation(FieldUrl.class);
            //判断该属性是否有注解
            if(fu!=null){
                //根据注解时,使用的不同值区分属性
                if (fu.value().equals("1")) {
                    field.setAccessible(true);
                    field.set(t,"hello one");//对Test类中变量one进行赋值
                }else if (fu.value().equals("2")) {
                    field.setAccessible(true);
                    field.set(t,"hello two");
                }
            }
        }
        Method[] ms = c.getMethods();//获取类中的方法
        Log.i("urlTest=====","Method.size=="+ms.length);
        for (Method m:ms) {
//            Log.i("urlTest=====","Method.name=="+m.getName());
            MethodUrl mu = m.getAnnotation(MethodUrl.class);
            if(mu!=null){
                if(mu.value().equals("1")){
                    try {
                        m.invoke(t);
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }else if (mu.value().equals("2")){
                    try {
                      //相当于调用了 Test中 methodTwo("twotwotwo");
                        m.invoke(t,"twotwotwo");
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

然后调用getTestClass()方法,输出日志为:

//因为Test自身含有属性,方法,如serialVersionUID,notify(),wait()等,因此size值为下
12-29 03:38:03.236 2625-2625/com.stone.reflection I/urlTest=====: Field.size==4
12-29 03:38:03.237 2625-2625/com.stone.reflection I/urlTest=====: Method.size==12
12-29 03:38:03.237 2625-2625/com.stone.reflection I/urlTest=====: methodOne11111==hello one
12-29 03:38:03.238 2625-2625/com.stone.reflection I/urlTest=====: methodTwo11111==hello two
12-29 03:38:03.238 2625-2625/com.stone.reflection I/urlTest=====: methodTwo22222==twotwotwo

你可能感兴趣的:(java反射与注解的简单使用)