java - Kryo:readClassAndObject/ReadObject 和 WriteClassAndObject/WriteObject 之间的区别

标签 java scala kryo

我试图理解文档中的以下陈述:

如果对象的具体类未知并且该对象可能为空:

kryo.writeClassAndObject(output, object);

Object object = kryo.readClassAndObject(input);

如果不确切知 Prop 体类会怎样。

我有以下代码:

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,则不会。

Exception in thread "main" com.esotericsoftware.kryo.KryoException: Class cannot be created (missing no-arg constructor): com.romix.scala.serialization.kryo.ScalaProductSerializer

我只是不明白为什么。

之前使用相同的代码,我没有使用我的类 RawData,而是使用了 Map,它与 writeObject 和 ReadObject 一起工作就像一个魅力。因此我很困惑。

谁能帮忙理解一下吗?

最佳答案

区别如下:

  • 当您使用以下序列化器时,您可以使用 writeClassAndObjectreadClassAndObject:
    • 序列化一个基类型:一个接口(interface)、一个具有子类的类,或者 - 对于 Scala - 像 Product 这样的特征,
    • 需要反序列化对象的类型(即Class对象)来构造这个对象(没有这个类型,它不知道什么 构建),
    • 示例:ScalaProductSerializer
  • 当您使用以下序列化器时,您可以使用 writeObjectreadObject:

根据您的具体情况总结一下:

  • 当您反序列化 RawData 时:
    • ScalaProductSerializer 需要找出Product的确切类型来创建实例,
    • 因此它使用 typ: Class[Product] 参数来执行此操作,
    • 因此,只有 readClassAndObject 有效。
  • 当您反序列化 Scala 不可变映射( scala.collection.immutable.Map 作为 IMap 导入)时:
    • ScalaImmutableAbstractMapSerializer 不需要找出确切的类型 - 它使用IMap.empty来创建一个实例,
    • 因此,它不使用 typ: Class[IMap[_, _]] 参数,
    • 因此,readObjectreadClassAndObject 都可以工作。

关于java - Kryo:readClassAndObject/ReadObject 和 WriteClassAndObject/WriteObject 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52337925/

相关文章:

java - Spark Kryo 异常 - 类未注册 : com. google.common.base.Present

java - 如何在 spring mvc 中验证电子邮件 ID 是否存在?

java - 使用 Java 的 Http 流

java - 如何让这段代码打印一个数字中有多少个素数?

java - 从 DialogFragment 调用 FileProvider 时出错 - 引用对象为空,

scala - 如何在 Scala Slick 中运行补丁/部分数据库更新?

scala - scala ReplaceFirst 令人困惑

java - 如何在 Scala 中子类化 Exception

apache-spark - 从 Spark RDD 读取 Kryo 文件

scala - 了解 Kryo 序列化缓冲区溢出错误