android - 无法在 Kryo 中使用泛型字段序列化泛型类

标签 android generics serialization kryo

我在使用 Kryo 时遇到了一个奇怪的问题。我可以很好地序列化一个泛型类(例如 List)。我什至可以序列化一个没有通用字段的通用类。但是,如果我用通用字段序列化一个通用类,它就会失败。一个例子应该能说明问题。

这是我要序列化的类:

import java.util.ArrayList;

public class GenericClass<T>
{
    private final ArrayList<T> list;

    public GenericClass()
    {
        list = new ArrayList<T>();
    }
}

这是测试它的代码。第二次调用 writeClassAndObject() 抛出异常。 ArrayList 的写入只是为了证明它工作得很好。

public void testWhySoDumb()
{
    File s = Environment.getExternalStorageDirectory();
    String dir = s.getAbsolutePath() + "/pagetest";
    String fileLocation = dir + "/filetest";
    new File(dir).mkdirs();
    Output output = null;

    Kryo kryo = new Kryo();
    kryo.setAsmEnabled(true);
    kryo.setDefaultSerializer(CompatibleFieldSerializer.class);

    // Test writing ArrayList (this works)
    List<Integer> arrayList = new ArrayList<Integer>();

    try
    {
        output = new Output(new FileOutputStream(fileLocation));
        kryo.writeClassAndObject(output, arrayList);
    }
    catch (Exception e)
    {
        System.out.println(e.getMessage()); // No problem here
    }
    finally
    {
        if (output != null)
        {
            output.close();
        }
    }

    // Test writing GenericClass (this does NOT work)
    GenericClass<Integer> genericClass = new GenericClass<Integer>();

    try
    {
        output = new Output(new FileOutputStream(fileLocation));
        kryo.writeClassAndObject(output, genericClass); // throws exception!!! <------
    }
    catch (Exception e)
    {
        System.out.println(e.getMessage()); 
    }
    finally
    {
        if (output != null)
        {
            output.close();
        }
    }
}

我收到以下异常:

com.esotericsoftware.kryo.KryoException: java.lang.IllegalArgumentException: type cannot be null.
Serialization trace:
list (com.myapp.page.history.GenericClass)
at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:82)
at com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer.write(CompatibleFieldSerializer.java:42)
at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:624)
at com.myapp.page.history.TestGenerics.testWhySoDumb(TestGenerics.java:57)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)
Caused by: java.lang.IllegalArgumentException: type cannot be null.
at com.esotericsoftware.kryo.Kryo.isFinal(Kryo.java:1135)
at com.esotericsoftware.kryo.serializers.CollectionSerializer.setGenerics(CollectionSerializer.java:60)
at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:60)
... 15 more

非常奇怪的是,如果我将“列表”的类型从“ArrayList”更改为“T”,它工作正常。 Kryo 似乎不知道如何处理 ArrayList 字段。我正在使用 Kryo 版本 3.0.0。

谢谢!

最佳答案

不知道你是否还有这个问题。我可能会认为这是版本问题或特定于 Android 的问题,因为这应该适用于当前版本。

Kryo kryo = new Kryo();
Output output = new Output(new FileOutputStream("fileLocation"));
kryo.writeObject(output, new GenericClass<String>());

关于android - 无法在 Kryo 中使用泛型字段序列化泛型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27909061/

相关文章:

android - 安装完成后自动启动 Android 应用程序

android studio模拟器加载但不工作

c# - 为什么使用 EF 序列化后得到无效的 JSON?

c# - 动态为什么/如何与泛型一起工作?

c# - 转换通用类型 "as T"同时强制执行 T 的类型

c# - 用C#在两个进程之间进行通信的最简单方法是什么?

c++ - 序列化具有不同成员的继承类 MFC c++

android - 是否可以分配一个热键来在 Android Studio 中的 Activity 和 XML 布局之间切换?

android - 在 Android studio 1.0.1 with API @ 21 and SDKTools @ 21.1.2 添加 Renderscript 导致构建错误

c# - 在 C# 中将子类型列表作为父类(super class)型列表返回