Android 插件化分析(1)- 反射

Java中有一个非常强大的技术:反射。通常我们可以使用反射技术去调用一个类的私有方法或者是访问和修改一个私有属性。

 

1. 如何获取一个类的类型

1.1 直接通过一个类的对象获取它的类型。

        String reflect = "reflect";
        Class clz = reflect.getClass();

1.2 通过类的命名空间和类名去获取类型

        try {
            // 获取EditText 类
            Class clz = Class.forName("android.widget.EditText");
            // 获取EditText的父类TextView
            Class parentClz = clz.getSuperclass();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

1.3 直接通过类本身的class属性获取类型

      Class clz = String.class;

1.4 TYPE属性,用于获取基本数据类型的类型

        // 获取的类型为boolean
        Class cla = Boolean.TYPE;
        
        // 获取的类型为 java.lang.Boolean
        Class clz = Boolean.class;

2 获取一个类的所有公有和私有的的方法和属性

2.1 获取构造函数

有这样一个类

public class ReflectClass {

    public ReflectClass() {
        System.out.println(ReflectClass.class.getSimpleName());
    }

    public ReflectClass(String a, Date date) {
        System.out.println(ReflectClass.class.getSimpleName() + " " + a.getClass().getSimpleName() + date.getClass().getSimpleName());
    }

    private ReflectClass(String a) {
        System.out.println(ReflectClass.class.getSimpleName() + " " + a.getClass().getSimpleName());
    }
}

我们可以获取这个类的所有构造函数或者指定参数列表的构造函数

        // 获取所有构造函数
        Class clz = ReflectClass.class;
        // 如果只想获取public构造函数使用 clz.getConstructors() 方法
        for (Constructor constructor : clz.getDeclaredConstructors()) {
            int mode = constructor.getModifiers();
            System.out.println("修饰域 " + mode);
            Class[] params = constructor.getParameterTypes();
            if (params.length == 0) {
                System.out.println("无参的构造函数");
            } else {
                for (Class cls : params) {
                    System.out.print(cls.getSimpleName() + " ");
                }
                System.out.println();
            }
        }

        // 直接获取指定参数列表的构造函数
        try {
            Class[] param = {String.class};
            Constructor constructor = clz.getDeclaredConstructor(param);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

2.2 调用构造函数生成对象

        // 直接获取指定参数列表的构造函数
        try {
            Class[] param = {String.class};
            Constructor constructor = clz.getDeclaredConstructor(param);
            // 如果是私有构造函数,调用前一定要先调用这个方法
            constructor.setAccessible(true);
            constructor.newInstance("abc");

            // 可以直接调用public无参构造函数
            clz.newInstance();

        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }

2.3 访问和修改方法和字段

public class ReflectClass {

    private int privateMemeber;

    private int publicMemeber;

    private static int staticMemeber;

    public ReflectClass() {
        System.out.println(ReflectClass.class.getSimpleName());

    }

    public ReflectClass(String a, Date date) {
        System.out.println(ReflectClass.class.getSimpleName() + " " + a.getClass().getSimpleName() + date.getClass().getSimpleName());
    }

    private ReflectClass(String a) {
        System.out.println(ReflectClass.class.getSimpleName() + " " + a.getClass().getSimpleName());
    }

    private void privateMethod() {
        System.out.println("privateMethod is called");
    }

    public void publicMethod() {
        System.out.println("publicMethod is called");
    }

    private static void staticMethod() {
        System.out.println("staticMethod is called");
    }

    @Override
    public String toString() {
        return "ReflectClass{" +
                "privateMemeber=" + privateMemeber +
                ", publicMemeber=" + publicMemeber +
                ", staticMemeber=" + staticMemeber +
                '}';
    }
}

        try {
            Class clz = ReflectClass.class;
            Object obj = clz.newInstance();

            // 获取所有的字段
            for (Field field : clz.getDeclaredFields()) {
                System.out.println("~~~~~~~~~~~获取字段~~~~~~~~");
                System.out.println(field.toString());
                // 非public字段在访问前一定要调用这个方法
                field.setAccessible(true);
                System.out.println(field.get(obj));
                if (field.getType() == int.class) {
                    field.set(obj , 1);
                } else if (field.getType() == boolean.class) {
                    field.set(obj,true);
                } else if (field.getType() == String.class) {
                    field.set(obj,"hello world");
                }
            }
            System.out.println("~~~~~~~~~~~获取字段结束~~~~~~~~");
            System.out.println(obj.toString());

            // 获取所有方法(不包括构造方法)
            for (Method method : clz.getDeclaredMethods()) {
            System.out.println("~~~~~~~~~~~方法~~~~~~~~");
                System.out.println(method.toString());
                method.setAccessible(true);
                method.invoke(obj,null);
            }

            // 静态方法可以直接调用
            Method method = clz.getDeclaredMethod("staticMethod",null);
            method.setAccessible(true);
            method.invoke(null,null);

        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值