反射(reflective)

反射(reflective):能够分析类能力的程序

先举个例子:

我在生产中遇到了一个情况,前端传给我的String字段中,凡事以 abcd结尾的字段 ,都是我需要进行处理的字段。现在为了防止特殊符号注入,我需要给诸如 % 这样的符号 加上一些 ("\")转义符。这个情况普遍存在在整个工程当中,那么可不可以将这个操作抽象成一个方法呢?

@Slf4j
public ModifyUtils {
    /**
     * 模糊查询以abcd结尾
     */
    private static final String LIKE_ENDING = "abcd";

    public static<T> ModifyLikeValues(final T t) {
        final Class clazz = t.getClass();
        //获取属性
        for (final Field f:clazz.getDeclaredFields()){
            //私有private设置可访问
            f.setAccessible(true);
            if (f.getName().length()<4){
                //长度不为4跳出本次循环(不可能以abcd结尾)
                continue;
            }
            final String endVals = f.getName().substring(f.getName().length()-4,f.getName().length());
            if (Objects.equals(endVals,LIKE_ENDING)){
                //截取后四位,发现是以abcd结尾
                try {
                    final PropertyDescriptor pd = new PropertyDescriptor(f.getName(), clazz);
                    //获取get方法
                    final Method readMethod = pd.getReadMethod();
                    //调get方法
                    final String values  = (String)readMethod.invoke(t);
                    //获取set方法
                    final Method setMethod = pd.getWriteMethod();
                    //还有值 调用set方法
                    setMethod.invoke(t,values.trim().replace("%","\%"));
                        
                    }
                } catch (IllegalAccessException e) {
                    log.info("异常1");
                    break;
                } catch (InvocationTargetException e) {
                    log.info("异常2");
                    break;                }
                catch (IntrospectionException e) {
                    log.info("异常3");
                    break;                }
            }else{
                    continue;
                    }
        }
        return t;
    }
}

(我这里就随便写个小例子,有一些问题这里没有解决,比如前端传递 A%B,这边没有操作)

分析:

Class c = t.getClass();

  Object 类的getClass()方法会返回一个class类型的实例(Class对象会描述一个特定类的属性)

常用的方法有:

Class:
1.getName  获取类的名字
2.Field[] getFields()
  Field[] getDeclaredFields()
  两个方法都是获取类的字段,区别在于,上一个获取的是公共的,下面的获取的是所有字段
3.Method[] getMethods()
  Method[] getDeclaredMethods()
  两个方法都是返回包含Method对象的数组(即方法),区别和field一样,上一个是获取公共的,下面的是获取全部
4.Constructor[] getConstructors()
  Constructor[] getDeclaredConstructors()
  返回Constructor对象的数组 上面是所有公共构造器 下面是所有构造器
     

我们先获取类的属性,所有字段,进行遍历,遍历时设置私有为可访问

            f.setAccessible(true);

然后我们获取属性名,获取后四位,判断是不是以abcd结尾的。不是进行下一个值的循环。continue是这个值结束进行下个值循环,break是直接跳出循环。

满足条件的我们需要获取它的get和set方法。比较原始的写法是直接拼名字,这边我们用 PropertyDescriptor  类来获取 get 和set method。构造这个类的时候第一个参数是 字段的名字  第二个参数是 类的实例。

获取到 method对象之后 ,调用invoke方法进行执行。invoke(object,args...)第一个参数是对象,第二个是调这个方法的参数,... 作用与 数组类似,就是可以直接传多个参数,用 ,隔开

想要更详细的看的可以参照《java核心技术卷1》p197  5.7 开始

链接: https://pan.baidu.com/s/1EiW-XsH4GehS41u6LC5Eqw 提取码: ng39

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值