我知道Serializable是一个标记接口。那么下面的方法签名是什么意思?
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData()
throws ObjectStreamException;
这是http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html
并在页面中将其写为“在序列化和反序列化过程中需要特殊处理的类必须实现具有这些精确签名的特殊方法:”
我很困惑。 Serializable是否是标记接口?
答案 0 :(得分:1)
是的,Serializable是一个标记界面。只有需要特殊处理的类才必须实现这些方法。
换句话说,可以实现这些方法中的一个或多个,以自定义类的实例的序列化或反序列化方式。通常不需要这样做,因为默认行为对于大多数需求来说是足够的。
答案 1 :(得分:0)
这些方法用于自定义序列化过程。我会举个例子。
class Person implements java.io.Serializable {
int id;
String name;
String city;
Person(int id, String name, String city) {
this.id = id;
this.name = name;
this.city = city;
}
private void writeObject(java.io.ObjectOutputStream stream)
throws IOException {
stream.writeInt("ID : " + id);
stream.writeObject("Name : " + name);
stream.writeObject("City : " + city);
}
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException {
id = stream.readInt();
name = (String) stream.readObject();
city = (String) stream.readObject();
}
public String toString() {
return id + "\t" + name + "\t" + city + "\t";
}
}
请注意,使用这些方法可以自定义序列化。在序列化默认序列化方法不会执行的字段时,我在writeObject方法中添加了字符串常量。
答案 2 :(得分:0)
我会在这里猜测原因。鉴于您可以使用标签来确定哪些字段是可序列化的,我首先想到的是序列化的内部工作方式,例如在ObjectOutputStream
中,是通过反射完成的。
所以也许writeObject
方法实际上也在检查是否存在在对象上定义了相同签名的私有方法,如果是,则调用该方法。最后,同样的方法已经可以使用反射来确定要序列化的字段和方法,因此检查特殊方法的存在并不是一个巨大的开销,我相信...
看起来有点奇怪,但听起来像是一个不错的解决方案。强制在界面中实现本来就太多了,因为大部分时间都是常见的。在像Java这样的单一继承模型中,使用抽象类是不可能的。 C#使用属性(相当于Java中的@
注释)。
希望有更多知识的人能够更多地了解这一点。 :)