c++ to_string 指定字符位数_ToString数据如何反序列化

7f12ee08f3c875b26ece0dd21005ec0b.png

不知道小伙伴们有没有这样的困扰,平常开发中写单测,要mock一个复杂的对象,并且也知道了该对象的toString格式数据(比如从日志中获取),但是该怎么构建这个对象呢?

如果是json格式可以直接通过json反序列化得到对象,那么toString格式如何反序列得到对象呢?

从反序列化原理来看,我们首先要解析出对象的一个个属性,toString对象属性格式为 k1=v1,k2=v2 ,那么可以按照逗号 , 作为分隔符解析出一个个token,注意一个token可以是基本类型的kv,比如 int/Interger/…/String 这种;也可以是对象类型,比如 object/array/list/map 等。解析出来token之后,基本类型的token可以直接通过反射将v设置到对象属性(Field)中;对象类型的token可以继续按照toString格式进行反序列化,直到全部数据都反序列化成功为止;针对 array/list/map 的数据要获取到对应元素的实际类型才能知道要反序列化的对象。对应的代码实现如下:

/**
 * toString格式反序列化类
 *
 * @author luoxiangnan
 * @date 2020-03-02
 */
public class ToStringUtils {

    /**
     * toString格式反序列化
     */
    @SuppressWarnings("all")
    public static <T> T toObject(Class<T> clazz, String toString) throws Exception {
        if (Objects.isNull(clazz) || Objects.isNull(toString) || StringUtils.isEmpty(toString)) {
            return clazz == String.class ? (T) toString : null;
        } else if (TypeValueUtils.isBasicType(clazz)) {
            return (T) TypeValueUtils.basicTypeValue(clazz, toString.trim());
        }

        toString = TokenUtils.cleanClassPrefix(clazz, toString.trim());
        toString = StringUtils.removeStart(toString, "(").trim();
        toString = StringUtils.removeEnd(toString, ")").trim();

        String token = null;
        T result = clazz.newInstance();
        while (StringUtils.isNotEmpty(toString) && StringUtils.isNotEmpty(token = TokenUtils.splitToken(toString))) {
            toString = StringUtils.removeStart(StringUtils.removeStart(toString, token).trim(), ",").trim();

            // 解析k/v格式的属性名/值
            Pair<String, String> keyValue = TokenUtils.parseToken(token);
            Field field = FieldUtils.getField(clazz, keyValue.getKey(), true);
            Object value = TypeValueUtils.buildTypeValue(field, keyValue.getValue());
            FieldUtils.writeField(field, result, value, true);
        }
        return result;
    }

    /**
     * 字符串解析类
     */
    static class TokenUtils {

        /**
         * 清除类名前缀字符串
         */
        static String cleanClassPrefix(Class clazz, String toString) {
            String simpleName = clazz.getSimpleName();
            if (clazz.getName().contains("$")) {
                // 内部类需要按照内部类名字格式
                String rowSimpleName = StringUtils.substringAfterLast(clazz.getName(), ".");
                simpleName = StringUtils.replace(rowSimpleName, "$", ".");
            }
            return to
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值