java - gson java中反序列化集合的困惑

标签 java gson

我对 gson 反序列化中的集合有疑问

结果:
第 1 行:编译没有任何错误。
第 2 行:编译没有任何错误。打印 [1.0, 2.0, 3.0, 4.0]。
第 2 行:抛出“线程“main”java.lang.ClassCastException 中的异常:java.lang.Double 无法转换为 gsonUserGuide.com.google.sites.A”

我的问题: 我知道我可以正确指定类型,如下所示。

ArrayList<Integer> aList = gson.fromJson( 
            "[1,2,3,4]", new TypeToken<ArrayList<Integer>>() {}.getType());

但我的问题是,如果它在第 3 行抛出 java.lang.ClassCastException,为什么它至少在运行时将值加载到 aList 时不会给出错误?

代码:

public class OBJConversion {

    private final static Gson gson = new Gson();

    public static void main(String[] args) {

        // Line 1
        ArrayList<A> aList = gson.fromJson("[1,2,3,4]", ArrayList.class);
        // Line 2
        System.out.println("main().aList : " + aList);
        // Line 3
        System.out.println("main().someString : " + aList.get(0).getSomeString());
    }

    class A {

        String someString = null;

        public String getSomeString() {
            return someString;
        }

        public void setSomeString(String someString) {
            this.someString = someString;
        }
    }
}

最佳答案

为什么

这是 Collections Limitations 之一使用 GSON 时:

You can serialize collection of arbitrary objects but can not deserialize from it because there is no way for the user to indicate the type of the resulting object.

GSON解释gson.fromJson("[1,2,3,4]", ArrayList.class)作为原语列表(它无法从 ArrayList<A> 得知您想要类型 A,因为类型信息在运行时丢失)。 GSON有different primitives与 Java 相比,并且没有 int ,所以[1,2,3,4]被视为双浮点精度的数字列表,Java Double 。因此,GSON 有效地创建了 List<Double> .

解决方法

GSON 建议 three workarounds :

  1. 手动解析它,如this example ,
  2. 注册 Collection.class 的类型适配器,或
  3. 注册 A 的类型适配器并使用fromJson(aList, Collection<A>.class) .

例如,选项 2 看起来像这样:

public class OBJConversion {

    public static void main(String[] args) {

        Gson gson = new GsonBuilder()
                // NOTE: all Lists will be treated as List<A>
                .registerTypeAdapter(List.class, new ACollectionAdapter())
                .create();

        // Line 1
        List<A> aList = gson.fromJson("[1,2,3,4]", List.class));
        // Line 2
        System.out.println("main().aList : " + aList);
        // Line 3
        System.out.println("main().someString : " + aList.get(0).getSomeString());
    }

    static class ACollectionAdapter extends TypeAdapter<List<A>> {

        @Override
        public void write(
                JsonWriter out, List<A> value) throws IOException {
            out.beginArray();
            for (A a : value) {
                out.value(a.getSomeString());
            }
            out.endArray();
        }

        @Override
        public List<A> read(JsonReader in) throws IOException {
            List<A> as = new ArrayList<A>();
            in.beginArray();
            while (in.hasNext()) {
                A a = new A();
                a.setSomeString(in.nextString());
                as.add(a);
            }
            in.endArray();
            return as;
        }
    }

    static class A {

        String someString = null;

        public String getSomeString() {
            return someString;
        }

        public void setSomeString(String someString) {
            this.someString = someString;
        }
    }
}

关于java - gson java中反序列化集合的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20949467/

相关文章:

java - Jenkins 如何在 Mac 内部设置 JAVA_HOME?

java - 你如何在java中获取float的尾数?

json - Tomcat servlet 对 json 对象表现得很奇怪

java - 使用 Gson 将 JSON 解析为 Java 类

JAVA使用Gson解析JSON(流模式)时出错: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

java - mongodb java 使用 gson 反序列化 long

java - GSON解析多个相同类型的key

java - 尝试运行包含依赖项的可执行 jar 时出现 UnsatisfiedLinkError

java - Arraylist 没有正确删除对象?

java - Java 类或 Android Activity 中的 Save File 方法?