为啥类的一个不可序列化的静态字段在实例被序列化时会抛出 NotSerializableException?
Posted
技术标签:
【中文标题】为啥类的一个不可序列化的静态字段在实例被序列化时会抛出 NotSerializableException?【英文标题】:Why a static field of a class, which is not serializable, will throw NotSerializableException when an instance being serialized?为什么类的一个不可序列化的静态字段在实例被序列化时会抛出 NotSerializableException? 【发布时间】:2019-03-28 17:12:55 【问题描述】:在scala中,我认为对象的一个字段在序列化时会是静态的,不会被序列化, 但如果该字段不可序列化,则会得到 NotSerializableException。 为什么 ?类似的java代码就可以了。
下面是一个简单的例子。
谢谢
Scala 代码:
package test
import java.io._
import java.util
object AStudent extends Serializable
var name="Jack"
val map=new util.WeakHashMap
object SerializationDemo extends App
val oos = new ObjectOutputStream(new FileOutputStream("./tmp/stu"))
println(AStudent.name)
AStudent.name=null
println(AStudent.name)
oos.writeObject(AStudent)
oos.close
Java 代码:
package test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.WeakHashMap;
public class Stu implements Serializable
public static String name="Jack";
public static WeakHashMap map=new WeakHashMap();
public static void main(String[] args) throws IOException
ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("./tmp/stu"));
oos.writeObject(new Stu());
oos.close();
【问题讨论】:
通常在询问异常时,您可能需要添加堆栈跟踪。除此之外,Scala 代码和 Java 代码不应该是等价的(虽然我不太了解 Scala),因为一个有实例字段,而另一个有类字段(又名静态)。 Scala 没有static
字段的概念。您可以“认为”对象A
的成员类似于Java 中的static
。关键字是“认为相似”而不是实际上是静态的。对象AStudent
将是匿名类AStudent.type
的一个实例,对象AStudent
的所有成员实际上都是类AStudent.type
的成员。
【参考方案1】:
这些例子并不相同。在 Java 示例中,您正在序列化 Stu
实例,序列化将跳过 static
字段,因为它们不是实例状态的一部分。在 Scala 示例中,您正在序列化具有 map
字段的 AStudent
对象实例。由于 Scala 没有 static
概念,Java 等价物是:
public class AStudent implements Serializable
public Map map = new WeakHashMap();
【讨论】:
【参考方案2】:Scala 没有static
字段的概念。您可以“认为”对象 A 的成员类似于 Java 中的 static
。
关键字是“认为类似于静态”而不是实际上是 static
。
对象AStudent
将是匿名类AStudent.type
的一个实例,对象AStudent
的所有成员实际上都是类AStudent.type
的成员
类似于,
class AStudentType[K, V](
var name: String ="Jack",
val map: WeakHashMap[K, V] = new WeakHashMap()
)
val AStudent = new AStudentType[String, String]()
【讨论】:
以上是关于为啥类的一个不可序列化的静态字段在实例被序列化时会抛出 NotSerializableException?的主要内容,如果未能解决你的问题,请参考以下文章
Java序列化之排除被序列化字段(transient/静态变量)