Pourquoi suis-je capable de sérialisez:Pourquoi la sérialisabilité scala diffère-t-elle dans les classes de cas avec les mêmes types de paramètres constructeurs?
// Serialize: OK
case class ClassWithType2[T:TypeTag](x:T) {
val tpe:java.lang.reflect.Type = Util.toJavaClass[T]
}
... mais pas
class TypeAware[T:TypeTag]() {
val tpe:java.lang.reflect.Type = Util.toJavaClass[T]
}
// Serialize: FAIL.
// No valid constructor for ClassWithType1
// in: java.io.ObjectStreamClass.checkDeserialize
case class ClassWithType1[T:TypeTag](x:T) extends TypeAware[T]
semblent tous deux avoir le même prototype de type constructeur:
[T:TypeTag](x:T)
et les deux s'étendre scala .Serializable et java.io.Serializable
val s1:Serializable = ClassWithType1(x=123)
val s2:Serializable = ClassWithType2(x=123)
val s3:java.io.Serializable = ClassWithType1(x=123)
val s4:java.io.Serializable = ClassWithType2(x=123)
Sa là une façon de mettre en œuvre des sous-classes TypeAware que:
- éviter d'avoir à déclarer dans tpe chaque sous-classe (comme ClassWithType2 fait)?
- permet à l'objet à sérialiser
Voici le harnais de test
class TypesTest {
@Test
def serializeTypeTest(): Unit = {
val obj2:Object = ClassWithType2(x=123)
Util.copyBySerialization(obj2) // Success!
val obj1:Object = ClassWithType1(x=123)
Util.copyBySerialization(obj1) // Fail
}
}
object Util {
def toJavaClass[T:TypeTag]: Class[_] = {
val tpe = typeOf[T]
runtimeMirror(tpe.getClass.getClassLoader).runtimeClass(tpe.typeSymbol.asClass)
}
def copyBySerialization[T](obj: T): T = deserialize(serialize(obj))
def serialize[T](obj: T): Array[Byte] = {
val byteOut = new ByteArrayOutputStream()
val objOut = new ObjectOutputStream(byteOut)
objOut.writeObject(obj)
objOut.close()
byteOut.close()
byteOut.toByteArray
}
def deserialize[T](bytes: Array[Byte]): T = {
val byteIn = new ByteArrayInputStream(bytes)
val objIn = new ObjectInputStream(byteIn)
val obj = objIn.readObject().asInstanceOf[T]
byteIn.close()
objIn.close()
obj
}
}
TypeAware ne prolonge pas java.io.Serializable. –
Pourquoi cela serait-il nécessaire? Je demande de sérialiser ClassWithType1, qui prétend être Serializable. NB. La sérialisation échoue car elle ne peut pas trouver un constructeur pour ClassWithType1, pas parce que TypeAware ou ses membres ne peuvent pas être sérialisés (la sérialisation de java.reflect.Type fonctionne correctement). – user48956
Toutes les quelques années, j'essaie de me rafraîchir la mémoire sur la sérialisation Java, mais je ne pense pas que ce soit le cas aujourd'hui. Mais vois ma réponse; le ctor n'est pas nul. –