2016-09-14 62 views
0

我想了解Scala中的序列化基礎知識。當我運行的第一個例子下面我得到的最後一行輸出如下:res1: A.Mao = [email protected]Scala中的序列化

@SerialVersionUID(1L) 
class Poo(val aa:Int) extends Serializable { 
    override def toString() = "Hola" 
} 
@SerialVersionUID(1L) 
class Mao(val hi: Poo) extends Serializable 

def serialize() = { 
    val test = new Mao(new Poo(1)) 
    try{ 
     val fout = new FileOutputStream("c:\\misc\\address.ser"); 
     val oos = new ObjectOutputStream(fout); 
     oos.writeObject(test); 
     oos.close(); 
     System.out.println("Done"); 
    }catch { 
    case ex => ex.printStackTrace(); 
    } 
}             
serialize()          

def ReadObjectFromFile[A](filename: String)(implicit m:scala.reflect.Manifest[A]): A = { 
    val input = new ObjectInputStream(new FileInputStream(filename)) 
    val obj = input.readObject() 
    obj match { 
    case x if m.erasure.isInstance(x) => x.asInstanceOf[A] 
    case _ => sys.error("Type not what was expected when reading from file") 
    } 
}             


ReadObjectFromFile[Mao]("c:\\misc\\address.ser") 

如果我改變了例子,用case classes,而不是事情與輸出

res1: A.Mao = Mao(Hola) 

case class Poo(val aa:Int) { 
    override def toString() = "Hola" 
} 

case class Mao(val hi: Poo) 

def serialize() = { 
    val test = new Mao(new Poo(1)) 
    try{ 
     val fout = new FileOutputStream("c:\\misc\\address.ser"); 
     val oos = new ObjectOutputStream(fout); 
     oos.writeObject(test); 
     oos.close(); 
     System.out.println("Done"); 
    }catch { 
    case ex => ex.printStackTrace(); 
    } 
}             

def ReadObjectFromFile[A](filename: String)(implicit m:scala.reflect.Manifest[A]): A = { 
    val input = new ObjectInputStream(new FileInputStream(filename)) 
    val obj = input.readObject() 
    obj match { 
    case x if m.erasure.isInstance(x) => x.asInstanceOf[A] 
    case _ => sys.error("Type not what was expected when reading from file") 
    } 
}             

ReadObjectFromFile[Mao]("c:\\misc\\address.ser") 

所以預期工作我問題是: 我需要做些什麼才能讓課程提供與案例課程相同的輸出?

爲什麼case類在沒有添加關於序列化的明確信息的情況下工作?

回答

2

這有什麼好做的德/序列化(這似乎是正確的) - 它只是結果是顯示方式:

斯卡拉REPL(和工作表)使用該值的toString方法來顯示它。案例類覆蓋默認的toString()方法,因此輸出很好地顯示(如預期)。對於非案例類,將調用Object.toString()的撤銷實現,並導致您看到的類名稱和地址。

您可以實現toString對非例類也一樣,獲得相同的結果:

class Mao(val hi: Poo) extends Serializable { 
    override def toString = s"Mao($hi)" 
} 

// program prints: 
// Done 
// Mao(Hola)