Java高级之注解、反射

本文探讨Java注解和反射的应用,包括它们在动态代理、代码注入和元编程中的角色。讲解了注解的保留策略,以及如何利用反射进行类、方法和变量的动态操作。文中以Android点击事件hook为例,展示了反射在实战中的应用,同时提及ASM库在字节码级别的操作。
摘要由CSDN通过智能技术生成

本文来自刘兆贤的博客_CSDN博客-Java高级,Android旅行,Android基础领域博主 ,引用必须注明出处!

Java的注解、反射等机制的产生,让动态代理成为可能,一般通过全限定名+类名,找到类,可以invoke它的构造方法以及其他方法,可以获取它的参数(Field)名称和值。

注解一般用在代码的注释上、代码审查上(有没有按标准写,比如inspect)、代码注入(hook,asbectj),需要考虑的是,在何时注入(编译期还运行期)

基础反射:获取类的变量名和变量值

    public static Map<String, Object> toMap(Object obj) {
        Map<String, Object> reMap = new HashMap<>();
        Class<?> clz = obj.getClass();//获取此对象运行期的Class对象
        while (clz != null) {
            Field[] fields = clz.getDeclaredFields();//获得类里声明的变量
            for (Field field : fields) {
                try {
                    String fieldName = field.getName();//获得变量名称
                    if (!extraParam(fieldName)) {
                        Field f = clz.getDeclaredField(fieldName);
                        f.setAccessible(true);
                        Object o = f.get(obj);//获得变量值
                        reMap.put(fieldName, o);
                    }
                } catch (NoSuchFieldException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            clz = clz.getSuperclass();//获得父类的Class对象,继续递归
        }
        return reMap;
    }

    private static boolean extraParam(String fieldName) {
        //以下三种变量,通常不需要写入
        return fieldName.equals("serialVersionUID")//用于根据变量产生,在恢复本地文件时,如果id不同,则类不同,就不需要再恢复(说明缓存已经过期)
                || fieldName.equals("shadow$_klass_")//API20以后出现,运行期对象的Class变量
                || fieldName.equals("shadow$_monitor_");//API20以后出现
    }

反射一般用在动态将json和Object互相转化,执行相关底层代码,比如设置某个类的Accessible为false,防止别人hook修改

例:阿里的FastJson解析:
@Override public <T> T json2Object(String json, Class<T> clazz) {

return JSON.parseObject(json, clazz);

}

@Override public String object2Json(Object instance) {

return JSON.toJSONString(instance);

}

例Java的默认注解策略:

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
	默认,编译时被抛弃
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the defau
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘兆贤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值