Крио: Разница между readClassAndObject / ReadObject и WriteClassAndObject / WriteObject - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь понять следующее утверждение из документации:

Если конкретный класс объекта неизвестен и объект может быть нулевым :

kryo.writeClassAndObject (output, object);

Object object = kryo.readClassAndObject (input);

Что делать, если конкретный класс точно не известен.

У меня следующий код:

case class RawData(modelName: String,
                   sourceType: String,
                   deNormalizedVal: String,
                   normalVal: Map[String, String])

object KryoSpike extends App {


  val kryo = new Kryo()
  kryo.setRegistrationRequired(false)
  kryo.addDefaultSerializer(classOf[scala.collection.Map[_,_]], classOf[ScalaImmutableAbstractMapSerializer])
  kryo.addDefaultSerializer(classOf[scala.collection.generic.MapFactory[scala.collection.Map]], classOf[ScalaImmutableAbstractMapSerializer])
  kryo.addDefaultSerializer(classOf[RawData], classOf[ScalaProductSerializer])

  //val testin = Map("id" -> "objID", "field1" -> "field1Value")
  val testin = RawData("model1", "Json", "", Map("field1" -> "value1", "field2" -> "value2") )

  val outStream = new ByteArrayOutputStream()
  val output = new Output(outStream, 20480)
  kryo.writeClassAndObject(output, testin)
  output.close()


  val input = new Input(new ByteArrayInputStream(outStream.toByteArray), 4096)
  val testout = kryo.readClassAndObject(input)
  input.close()
  println(testout.toString)

}

Когда я использую readClassAndObject и writeClassAndObject, это работает.Однако, если я использую writeObject и readObject, это не так.

Исключение в потоке "main" com.esotericsoftware.kryo.KryoException: невозможно создать класс (отсутствует конструктор без аргументов): com.romix.scala.serialization.kryo.ScalaProductSerializer

Я просто не понимаю, почему.

ранее, используя тот же код, вместо того, чтобы использовать мой класс RawData, я использовал карту, и она работала как шарм с writeObject и ReadObject.Поэтому я в замешательстве.

Может кто-нибудь помочь понять это?

1 Ответ

0 голосов
/ 15 сентября 2018

Разница заключается в следующем:

  • вы используете writeClassAndObject и readClassAndObject, когда используете сериализатор, который:
    • сериализует базовый тип : интерфейс, класс с подклассами или - в случае Scala - черту типа Product,
    • и нужен тип (то есть объект Class) десериализованного объекта для создания этого объекта (без этого типа он не знает что построить),
    • пример: ScalaProductSerializer
  • вы используете writeObject и readObject, когда используете сериализатор, который:
    • сериализует ровно один тип (то есть класс, который может быть создан; пример: EnumSetSerializer),
    • или сериализует более одного типа, но конкретный тип может быть как-то выведен из сериализованных данных (пример: ScalaImmutableAbstractMapSerializer)

Подводя итог для вашего конкретного случая:

  • при десериализации вашего RawData:
    • ScalaProductSerializer необходимо , чтобы узнать точный тип Product для создания экземпляра,
    • , поэтому для этого используется параметр typ: Class[Product],
    • в результате работает только readClassAndObject.
  • при десериализации неизменяемой карты Scala (scala.collection.immutable.Map импортируется как IMap):
    • ScalaImmutableAbstractMapSerializer не нужно , чтобы узнать точный тип - для создания экземпляра используется IMap.empty,
    • в результате не используется параметр typ: Class[IMap[_, _]],
    • в результате работают readObject и readClassAndObject.
...