2015-01-12 3 views
2

Я столкнулся с странной проблемой с Kryo. Я могу сериализовать общий класс (например, List) просто отлично. Я даже могу сериализовать общий класс, который не имеет общих полей. Однако, если я сериализую общий класс с общими полями, он терпит неудачу. Пример должен показать проблему.Невозможно сериализовать общий класс с общим полем в Kryo

Вот класс, я хочу, чтобы сериализации:

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.

Спасибо!

ответ

1

Я не знаю, есть ли у вас эта проблема. Вероятно, я думаю, что это проблема с версией или что-то особенное для Android, потому что это должно работать с текущей версией.

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