巧用Java反射手写简易版Fastjson

与其抱怨身处黑暗,不如独自提灯前行

前言

关于Fastjson的相关知识可以查看我的这篇博客:史上最全的JSON解析之Fastjson,而关于手写简易版Fastjson有什么用呢?其实如果在实际使用的过程中还是推荐使用阿里巴巴官方的Fastjson,毕竟有人都帮你写好了直接用就可以了,而且自己写的一般是没有阿里写的运行快啦。手写简易版Fastjson只是为了锻炼思维以及复习Java反射知识罢了。话不多说,为了节省大家的时间,下面直接进入编码过程。

编码实现

必要的解释都在代码的注释里

Java对象

事先准备好一个用于转换成JSON字符串的Java对象:

/**
 * @author guqueyue
 * @Date 2020/5/28
 * 人类
 **/
// lombok插件的注解
@Data // getter、setter以及toString方法
@AllArgsConstructor // 全参构造方法
@NoArgsConstructor // 无参构造方法
@Accessors(chain = true) // 开启链式编程
public class Person {

    /**
     * 姓名
     */
    private String name;

    /**
     * 性别
     */
    private String sex;

    /**
     * 年龄
     */
    private Integer age;
}

核心代码

模拟Fastjson中toJsonString()方法的核心代码:

/**
 * @author guqueyue
 * @Date 2020/5/28
 * 我自己的FastJson
 **/
public class MyJson {

    /**
     * 将任意对象转换为JSON字符串
     * @param object
     * @return
     */
    public static final String toJsonString(Object object) throws IllegalAccessException {

        // 获取反射对象
        Class<?> clazz = object.getClass();

        // 获取反射对象的所有属性,包括私有属性
        Field[] fields = clazz.getDeclaredFields();

        // 创建字符串类,便于拼接出JSON字符串
        StringBuffer stringBuffer = new StringBuffer();
        String str = "";
        stringBuffer.append("{");
        // 遍历所有属性
        for (Field field : fields) {

            // 第一次无须拼接逗号
            if (stringBuffer.length() != 1) {
                stringBuffer.append(",");
            }

            // 给私有属性授权,以便能够对于私有属性操作
            field.setAccessible(true);

            stringBuffer.append("\"");
            stringBuffer.append(field.getName());
            stringBuffer.append("\"");

            stringBuffer.append(":");

            // 两种判断属性值是否为字符串类型的方式
            Boolean flag = field.getType().isInstance(str);
//            Boolean flag = field.getType().toString().equals("class java.lang.String");
            if (flag) { // 如果属性的类型为字符串,则给属性值加上双引号
                stringBuffer.append("\"");
                stringBuffer.append(field.get(object));
                stringBuffer.append("\"");
            } else {
                stringBuffer.append(field.get(object));
            }

        }
        stringBuffer.append("}");

        return stringBuffer.toString();
    }
}

实现效果

让我们来测试一下,看一下效果:

/**
 * @author guqueyue
 * @Date 2020/5/28
 **/
public class FastJsonTest {

    public static void main(String[] args) throws IllegalAccessException {

        // 创建需要转换的对象
        Person person = new Person()
                            .setName("小明")
                            .setSex("男")
                            .setAge(17);
        // 将对象转换为Json字符串
        String jsonString = MyJson.toJsonString(person);
        // 打印到控制台
        System.out.println(jsonString);
    }
}

运行程序,控制台打印为:
在这里插入图片描述
转换成功!

答疑解惑

这个时候可能有小伙伴会问了:感觉你这个好麻烦呀,我不用反射不是也可以吗?如下所示:

/**
 * @author guqueyue
 * @Date 2020/5/28
 * 不用反射将Java对象转换成JSON字符串
 **/
public class MyTest {
    public static void main(String[] args) {

        // 创建需要转换的对象
        Person person = new Person()
                .setName("小明")
                .setSex("男")
                .setAge(17);

        // 将对象转换为Json字符串
        String jsonString = myJsonString(person);
        // 打印到控制台
        System.out.println(jsonString);
    }

    private static String myJsonString(Person person) {

        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("{\"name\":\"");
        stringBuffer.append(person.getName() + "\",\"sex\":\"");
        stringBuffer.append(person.getSex() + "\",\"age\":");
        stringBuffer.append(person.getAge() + "}");

        return stringBuffer.toString();
    }
}

运行效果为:
在这里插入图片描述
这样看来似乎不用反射不但更加简单,而且实现效果也相同。那为什么连阿里巴巴研发的Fastjson内部也是用反射写的?难道阿里巴巴的人故意把简单的问题复杂化是在炫技吗?当然不是,因为不用重复造轮子的终极奥义就在于虽然造轮子的过程可能比较复杂,但我只需要编写一次,之后无论是什么对象我就可以直接使用。而第二种方式看起来虽然简单,但是每一次转换不同的Java对象成JSON字符串就要重新编写代码。又或者,难不成你要写一堆if-else判断穷尽世界上所有的Java对象,然后事先编写好所有的代码吗?

猜你喜欢

转载自blog.csdn.net/Qizhi_Hu/article/details/106388260