scala序列化总是抛出异常,为什么?

标签 scala exception serialization

我有这个小 scala 代码片段:

@SerialVersionUID(43L) class p(val a:Int=14,val b:Double=3.0) extends Serializable{
}
import java.io._

val out = new ObjectOutputStream(new FileOutputStream("my.obj"))
out.writeObject(new p(5,7))
out.close()

val in = new ObjectInputStream(new FileInputStream("my.obj"))
val savedPerson=in.readObject.asInstanceOf[p]
println(savedPerson.a)

当我在windows或mac上运行它时,它打印出巨大的异常信息:

java.io.NotSerializableException: Main$$anon$1
    at java.base/java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.base/java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.base/java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.base/java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.base/java.io.ObjectOutputStream.writeObject(Unknown Source)
    at Main$$anon$1.errorFunction(ch09.scala:52)
    at Main$$anon$1.<init>(ch09.scala:110)
    at Main$.main(ch09.scala:1)
    at Main.main(ch09.scala)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at scala.reflect.internal.util.ScalaClassLoader.$anonfun$run$2(ScalaClassLoader.scala:98)
    at scala.reflect.internal.util.ScalaClassLoader.asContext(ScalaClassLoader.scala:32)
    at scala.reflect.internal.util.ScalaClassLoader.asContext$(ScalaClassLoader.scala:30)
    at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:129)
    at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:98)
    at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:90)
    at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:129)
    at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:22)
    at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:21)
    at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
    at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:29)
    at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:28)
    at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
    at scala.tools.nsc.ScriptRunner.runCompiled(ScriptRunner.scala:170)
    at scala.tools.nsc.ScriptRunner.$anonfun$runScript$1(ScriptRunner.scala:187)
    at scala.tools.nsc.ScriptRunner.$anonfun$runScript$1$adapted(ScriptRunner.scala:187)
    at scala.tools.nsc.ScriptRunner.$anonfun$withCompiledScript$2(ScriptRunner.scala:156)
    at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:124)
    at scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:200)
    at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:70)
    at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:85)
    at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

这是什么错误?我该如何修复它?我不太明白这一点。 谢谢!

最佳答案

我从您的堆栈跟踪中看到您正在使用脚本运行程序:

scala -nc noser.scala

我将脚本命名为 Yessir,不,先生,因为没有发生序列化。

-nc 避免启动编译服务器守护进程。

如果脚本运行程序没有看到具有 main 方法的对象,它会将您的脚本代码打包到它为您构造的 main 方法的本地类中。

def main(args: Array[String]) = { class anon_class { code } ;新的 anon_class() }

您的代码在构造函数中运行,这也不是一个好主意。

您可以使用 -Xprint:typer,flatten 看到这一点。或者尝试使用 -Xprint:all

您的可序列化类有一个指向匿名本地类的外部指针,而匿名类是不可序列化的。

也许外部指针只是一个错误。或者不,请参阅下面的引用。它需要一个提示来消除外部指针,例如将类设为final

我看到有类似的错误,例如 this one where the enclosing module is captured by a lambda .

您的解决方法是将代码放在对象的 main 方法中,或将所有内容包装在 App 中。

object Main extends App {
  // code
}

另一个解决方法是使可序列化类成为final。有讨论on this ticketrelated票和 fix .

关于scala序列化总是抛出异常,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50782864/

相关文章:

scala - 与 pipeTo 等效的 Akka 类型是什么?

c++ - 为什么 ideone.com 这样做?

java - 如何访问作为线程的一部分发生的异常信息?

C++、ECS 和保存/加载

arrays - 如何在 MATLAB 中将 .mat 文件内容保存到内存中?

java - 是否可以在不调用任何构造函数的情况下实例化一个类?

scala - 在 Ammonite 中导入 $ivy

scala - 为什么 Akka HTTP 路由捕获我的异常?

jsp - HTTP 状态 405 - JSP 仅允许 GET POST 或 HEAD

Scala 等价于 Haskell 单子(monad)