博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数组 JSON字符串 数组过程中的问题
阅读量:5886 次
发布时间:2019-06-19

本文共 7376 字,大约阅读时间需要 24 分钟。

阅读原文请访问我的博客 之前在使用
alibaba的fastjson做数组的相关转换操作的时候遇到一些问题,这里把遇到的问题以及如何解决的记录如下。

一. 转换过程中的问题

话不多说,先上代码。

public class JsonTest {    public static void main(String[] args) {        //创建一个String数组        String[][] stringArray = new String[][]{
{
"1","2","3"},{
"4","5","6"}}; //使用fastjson转为json字符串 String jsonString = JSON.toJSONString(stringArray); System.out.println(jsonString); //解析json字符串后输出class发现是jsonArray的。 Object array = JSON.parse(jsonString); System.out.println(array.getClass()); }}复制代码

输出结果是:

Before class:class [[Ljava.lang.String;[["1","2","3"],["4","5","6"]]After class:class com.alibaba.fastjson.JSONArray复制代码

遇到的问题如上,把一个数组转为json字符串后,再使用用JSON.parse()转换回来,获取到的class类型却是JSONArray的。

当然你也可以用很简单的办法把他给转换成需要的String二维数组。不过我的需求是:

  1. 只知道是个数组,知道到数组的原始Class类型(如果是String[][]知道是String.class)
  2. 不知道是几维数组,也不知道最开始传入的数组的长度
  3. 在拿到从Json字符串转换回来的object的时候,必须要使用原始类型(比如是String[][],那么转换回来的object,使用object.getClass()应该得到[[Ljava.lang.String),否则无法使用。

为了解决上述问题,在网上查阅各种资料无果,最后突然想到查询数组的反射,找到了java.lang.reflect.Array这个包,下面对这个包里面的一些使用做一个简单的介绍。

二. 关于java.lang.reflect.Array

同样先上代码:

public class ArrayTest {    /**     * 创建一维数组.     * @param cls 数组基本类型Class     * @param length 创建数组长度     * @return 创建的数组     */    public static Object creatOneDimArray(Class cls, int length) {        return Array.newInstance(cls, length);    }    /**     * 创建多维数组.     * @param cls 数组基本类型Class     * @param dims 维度信息     * @return 创建的数组     */    public static Object creatMultiDimsArray(Class cls, int[] dims) {        return Array.newInstance(cls, dims);    }    /**     * 获取数组的长度和class信息.     * @param array 使用Array.newInstance()创建的array     * @return 长度和class信息     */    public static String getArrayInfo(Object array) {        Class cls = array.getClass();        //只会返回第一维度的长度,比如String[1][2][3]返回1,String[3][4]返回3        int length = Array.getLength(array);        return "CLASS:" + cls + "-----" + "LENGTH:" + length;    }    public static void main(String[] args) {        //创建长度为10的一维String数组        Object oneArray = creatOneDimArray(String.class, 10);        System.out.println(getArrayInfo(oneArray));        //创建一个[2,3,4]的二维String数组        int[] dims = new int[]{
2,3,4}; Object threeArray = creatMultiDimsArray(String.class,dims); System.out.println(getArrayInfo(threeArray)); //************************** //* 数组赋值操作 * //************************** //---------1.强制转换赋值 ((String[])oneArray)[1] = "hello"; ((String[])oneArray)[9] = " world"; System.out.println(((String[])oneArray)[1] + ((String[])oneArray)[9]); ((String[][][])threeArray)[1][2][3] = "hello"; ((String[][][])threeArray)[0][1][3] = " java"; System.out.println(((String[][][])threeArray)[1][2][3] + ((String[][][])threeArray)[0][1][3]); //--------2.使用Array.set()进行赋值操作 //使用Array.get()可以获取到下一维的值,比如三维的获取到二维 //获取三维中index=1的二维数组,Strign[1][][]。 Object two = Array.get(threeArray,1); //从输出可以看到获取到的是一个二维数组 System.out.println("CLASS:" + two.getClass()); //对String[1][0][]赋值 Array.set(two,0,new String[]{
"this"," is"," a"," test"}); System.out.println(((String[][][])threeArray)[1][0][0] + ((String[][][])threeArray)[1][0][1] + ((String[][][])threeArray)[1][0][2] + ((String[][][])threeArray)[1][0][3]); //再获取一维String[1][1][] Object one = Array.get(two,1); System.out.println("CLASS:" + one.getClass()); Array.set(one,0,"my"); Array.set(one,1," name"); Array.set(one,2," is"); Array.set(one,3," brightloong"); System.out.println(((String[][][])threeArray)[1][1][0] + ((String[][][])threeArray)[1][1][1] + ((String[][][])threeArray)[1][1][2] + ((String[][][])threeArray)[1][1][3]); }}复制代码

输出结果是:

CLASS:class [Ljava.lang.String;-----LENGTH:10CLASS:class [[[Ljava.lang.String;-----LENGTH:2hello worldhello javaCLASS:class [[Ljava.lang.String;this is a testCLASS:class [Ljava.lang.String;my name is brightloong复制代码

这里已经在上述代码中做了大部分的注释,这里也不在详细介绍,主要说一下几个方法的作用。

  • Array.newInstance(Class<?> componentType, int length)Array.newInstance(Class<?> componentType, int... dimensions)第一个用于创建传入类型的长度为length的一维数组,第二个可以用于创建传入类型的多维数组,维度和长度由传入的第二个参数决定。
  • Array.get(Object array, int index)用于获取传入的数组array的index下的内容。
  • Array.set(Object array, int index, Object value)用于对传入的数组array的index进行赋值,赋值为value,具体使用见上述的代码。

三. 如何解决转换问题

在具备了以上的了解后,再来解决所遇到的问题。

public class JsonArrayToArray {    public static void main(String[] args) {        //创建一个String数组        String[][] stringArray = new String[][]{
{
"1","2","3"},{
"4","5","6"}}; //使用fastjson转为json字符串 String jsonString = JSON.toJSONString(stringArray); System.out.println(jsonString); //解析json字符串后输出class发现是jsonArray的。 Object array = JSON.parse(jsonString); System.out.println(array.getClass()); Object realArray = null; try { realArray = getArrayInstanceByClassAndArg(String.class, array); } catch (ClassNotFoundException e) { e.printStackTrace(); } parseJsonArray(array, realArray); System.out.println(realArray.getClass()); System.out.println(realArray.getClass().equals(String[][].class)); } /** * 解析jsonArray还原为最开始的数组 * @param o 解析后的类型是jsonArray的参数 * @param array 实际要组装的数组 */ private static void parseJsonArray(Object o, Object array) { parseJsonArray(o, array, null, 0); } /** * 利用递归调用,解析jsonArray还原为最开始的数组 * @param o 解析后的类型是jsonArray的参数 * @param array 实际要组装的数组 * @param lastArray 上一个array * @param index index */ private static void parseJsonArray(Object o, Object array, Object lastArray, int index) { JSONArray tempArray; //如果class不是JSONArray,使用Array.set()赋值 if (!o.getClass().equals(JSONArray.class)) { Array.set(lastArray,index , o); return; } //如果是JSONArray,继续继续循环递归调用 tempArray = (JSONArray)o; for (int i = 0; i < tempArray.size(); i++) { Object arrayTemp = Array.get(array, i); parseJsonArray(tempArray.get(i), arrayTemp, array, i); } } /** * 根据class和传入的解析后的类型是jsonArray的参数,获取对应维度和大小的数组 * @param cls Class * @param argValue 解析后的类型是jsonArray的参数 * @return 返回数组 * @throws ClassNotFoundException 异常 */ private static Object getArrayInstanceByClassAndArg(Class cls, Object argValue) throws ClassNotFoundException { Object temp = argValue; JSONArray tempArray; List
dimsInf = new ArrayList
(); //获取jsonArray对应的数组维度和长度 while (temp.getClass().equals(JSONArray.class)) { tempArray = (JSONArray)temp; dimsInf.add(tempArray.size()); temp = tempArray.get(0); } int[] dims = new int[dimsInf.size()]; for (int i = 0; i < dimsInf.size(); i++) { dims[i] = dimsInf.get(i); } //返回对应的数组 return Array.newInstance(cls, dims); }}复制代码

输出结果是:

[["1","2","3"],["4","5","6"]]class com.alibaba.fastjson.JSONArrayclass [[Ljava.lang.String;true复制代码

可以看到最后被将转换后的Class为JSONArray的结果在转换为最初的数组类型,String[][],由最后realArray.getClass().equals(String[][].class)返回结果true也可以得到确实转换正确了。具体的解析方法可以看上面的parseJsonArray()方法。

转载于:https://juejin.im/post/5add8ea66fb9a07aa9255545

你可能感兴趣的文章
tomcat端口配置规范
查看>>
ubuntu 下crontab
查看>>
一步步安装nginx搭建流媒体服务器
查看>>
部署keepalived
查看>>
Android------底部导航栏BottomNavigationBar
查看>>
用memcached做实时分页缓存
查看>>
java运算符
查看>>
《Genesis-3D游戏引擎系列教程-高级篇》1:后期效果
查看>>
Jquery基本操作
查看>>
WM_COMMAND产生的条件
查看>>
http响应Last-Modified和ETag
查看>>
MySQL索引类型一览 让MySQL高效运行起来
查看>>
Linux下启动停止查看杀死Tomcat进程
查看>>
bt分析之bt种子发布---做种(2)
查看>>
makefile(一)makefile文件组成
查看>>
我的友情链接
查看>>
Java异步线程池中处理logback MDC
查看>>
CentOS 6.3开机自动联网
查看>>
springMVC 拦截器 HandlerInterceptor 用法
查看>>
C# System.Data.OracleClient requires Oracle client software version 8.1.7 or greater
查看>>