scala сериализация всегда выдает исключение, почему? - PullRequest
0 голосов
/ 10 июня 2018

У меня есть небольшой фрагмент кода 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)

Что такое ошибкаэтот?Как я могу это исправить?Я не совсем понимаю это.Спасибо!

1 Ответ

0 голосов
/ 11 июня 2018

Я вижу из вашей трассировки стека, что вы используете скрипт запуска:

scala -nc noser.scala

, где я назвал скрипт как в Yessir, нет, сэр, потому что естьсериализация не происходит.

-nc избегает запуска демона сервера компиляции.

Если исполнитель сценариев не видит объект с методом main, он упаковывает код сценария в класс, которыйявляется локальным по отношению к основному методу, который он создает для вас.

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

Ваш код выполняется в конструкторе, что тоже не очень хорошая идея.

Выможно увидеть это с помощью -Xprint:typer,flatten.Или поэкспериментируйте с -Xprint:all.

Ваш сериализуемый класс имеет внешний указатель на анонимный локальный класс, а анонимный класс не сериализуем.

Возможно, внешний указатель - просто ошибка.Или нет, см. Ссылку ниже.Требуется подсказка для устранения внешнего указателя, например, создание класса final.

. Я вижу, что были подобные ошибки, такие как , в этом случае, когда закрывающий модуль захвачен лямбдой .

Ваш обходной путь - поместить ваш код в метод main объекта или обернуть все в App.

object Main extends App {
  // code
}

Другой обходной путь - сделать сериализуемый класс * 1035.*.Существует обсуждение для этого билета и связанных билетов и fix .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...