java “Serializable”类的子类是否自动“Serializable”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25666385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is a subclass of a "Serializable" class automatically "Serializable"?
提问by Benas
Does a child class of a class that implements the Serializable
interface also implement Serializable
? In other words, can instances of the child class also be serialized?
实现Serializable
接口的类的子类是否也实现了Serializable
?换句话说,子类的实例也可以序列化吗?
回答by Stephen C
I wanted to ask whether the child of the parent, which implements "Serializable" interface, implements "Serializable" interface too, or in other words can that child be serialized?
我想问一下实现“Serializable”接口的parent的孩子是否也实现了“Serializable”接口,或者换句话说,那个孩子可以被序列化吗?
The answer to the first part is Yes. That comes as a natural consequence of Java inheritance.
第一部分的答案是肯定的。这是 Java 继承的自然结果。
The answer to the second part is Not Always!
第二部分的答案并非总是如此!
Consider this:
考虑一下:
public class Parent implements Serializable {
private int i;
// ...
}
public class Child extends Parent {
private final Thread t = new Thread(); // a non-serializable object
// ...
}
An instance of Parent
can be serialized, but an instance of Child
cannot ... because it has an attribute whose type (Thread
) is not serializable.
的实例Parent
可以被序列化,但 的实例Child
不能……因为它有一个类型 ( Thread
) 不可序列化的属性。
(Now if t
was declared as transient
, or if Child
avoided using the default serialization mechanism, Child
could be serializable. But my point is that serializability is an emergent property, not an inheritable property.)
(现在 ift
被声明为transient
,或者如果Child
避免使用默认的序列化机制,则Child
可以被序列化。但我的观点是可序列化是一个紧急属性,而不是一个可继承的属性。)
回答by Elliott Frisch
Yes. If a parent implements Serializable
then any child classes are also Serializable
.
是的。如果父Serializable
类实现,则任何子类也是Serializable
.
static class A implements Serializable {
}
static class B extends A {
}
public static void main(String[] args) {
Serializable b = new B(); // <-- this is a legal statement.
}
B
also implements Serializable
.
B
也实现Serializable
.
回答by Uts
Short Answer: Yes, If Parent is Serialized then child class is automatically Serialized.
简短回答:是的,如果父类已序列化,则子类将自动序列化。
Long Answer:
长答案:
If Parent class is Serializable then child class is by default Serializable. JVM checks if the parent class implements Serializable and if so, it considers child class also as serializable. Hence, Serialization is a inheritable concept which comes from parent to child.
public class ParentSerializableNotChild {
public static void main(String[] args) throws Exception{ Child chileSerialize = new Child(); //Serialization FileOutputStream fos = new FileOutputStream("test.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(chileSerialize); FileInputStream fis = new FileInputStream("test.ser"); ObjectInputStream ois = new ObjectInputStream(fis); Child childDeserialize = (Child) ois.readObject(); System.out.println(childDeserialize.i + "---" + childDeserialize.j); //10---20 } } class Parent implements Serializable{ int i = 10; } class Child extends Parent{ int j = 20; }
If parent class is not serializable then also child class can be serialized. Best example of this is Object class, Object class does not implements Serializable but any class which is child of Object class can implement Serializable.
public class ChildSerializedParentNot {
public static void main(String[] args) throws Exception{ Dogy d = new Dogy(); d.i = 888; d.j = 999; FileOutputStream fos = new FileOutputStream("inheritance.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); System.out.println("Serializing"); oos.writeObject(d); FileInputStream fis = new FileInputStream("inheritance.ser"); ObjectInputStream ois = new ObjectInputStream(fis); System.out.println("Deserializing"); Dogy d2 = (Dogy) ois.readObject(); System.out.println(d2.i + "-----" + d2.j); } } class Animal{ int i = 10; Animal(){ System.out.println("Parent class cons"); } } class Dogy extends Animal implements Serializable{ Dogy(){ System.out.println("Child class constructor"); } int j = 20; }
如果父类是可序列化的,那么子类默认是可序列化的。JVM 检查父类是否实现了 Serializable,如果是,它也将子类视为可序列化。因此,序列化是一个从父级到子级的可继承概念。
公共类 ParentSerializableNotChild {
public static void main(String[] args) throws Exception{ Child chileSerialize = new Child(); //Serialization FileOutputStream fos = new FileOutputStream("test.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(chileSerialize); FileInputStream fis = new FileInputStream("test.ser"); ObjectInputStream ois = new ObjectInputStream(fis); Child childDeserialize = (Child) ois.readObject(); System.out.println(childDeserialize.i + "---" + childDeserialize.j); //10---20 } } class Parent implements Serializable{ int i = 10; } class Child extends Parent{ int j = 20; }
如果父类不可序列化,那么子类也可以序列化。最好的例子是 Object 类,Object 类不实现 Serializable 但任何 Object 类的子类都可以实现 Serializable。
公共类 ChildSerializedParentNot {
public static void main(String[] args) throws Exception{ Dogy d = new Dogy(); d.i = 888; d.j = 999; FileOutputStream fos = new FileOutputStream("inheritance.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); System.out.println("Serializing"); oos.writeObject(d); FileInputStream fis = new FileInputStream("inheritance.ser"); ObjectInputStream ois = new ObjectInputStream(fis); System.out.println("Deserializing"); Dogy d2 = (Dogy) ois.readObject(); System.out.println(d2.i + "-----" + d2.j); } } class Animal{ int i = 10; Animal(){ System.out.println("Parent class cons"); } } class Dogy extends Animal implements Serializable{ Dogy(){ System.out.println("Child class constructor"); } int j = 20; }
Output:
Parent class cons
Child class constructor
Serializing
Deserializing
Parent class cons
10-----999
输出:
父类 cons
子类构造函数
Serializing
Deserializing
Parent class cons
10-----999
From above, there are 3 cases which happens when a child is serialized but not parent.
从上面可以看出,当孩子被序列化而不是父母时,会发生 3 种情况。
Case 1: During Serialization, JVM checks if any instance variable is coming from non serialized parent class. If so, that the parent class is not serializable and its instance variable participates in serialization then jvm ignores the value of the instance variable and stores default value in the file. (In above example, i is stored as 0 in file).
情况 1:在序列化期间,JVM 检查是否有任何实例变量来自非序列化父类。如果是这样,则父类不可序列化并且其实例变量参与序列化,则 jvm 忽略实例变量的值并将默认值存储在文件中。(在上面的例子中,i 在文件中存储为 0)。
Case 2: During Deserialization, JVM checks if any instance variable is coming from non serialized parent class. If so, JVM will run the INSTANCE CONTROL FLOW and the original value of the object will be restored.
情况 2:在反序列化期间,JVM 检查是否有任何实例变量来自非序列化父类。如果是这样,JVM 将运行 INSTANCE CONTROL FLOW 并恢复对象的原始值。
INSTANCE CONTROL FLOW(In short) http://java2bigdata.blogspot.in/2015/05/instance-control-flow-in-java.html:
1. Identification of Instance member.
2. Execution of instance variable assignment & instantiation.
3. Execution of constructor.
实例控制流程(简而言之)http://java2bigdata.blogspot.in/2015/05/instance-control-flow-in-java.html:
1. 实例成员的识别。
2. 执行实例变量赋值和实例化。
3. 构造函数的执行。
Case 3: Since in instance control flow, constructor is executed. Hence, in case of Non serialized parent a no-arg constructor is called, that constructor can be user provided or jvm created. If there is no no-arg constructor then it will result in InvalidClassException.
情况 3:由于在实例控制流中,执行构造函数。因此,在非序列化父级的情况下,调用无参数构造函数,该构造函数可以由用户提供或由 jvm 创建。如果没有无参数构造函数,则会导致 InvalidClassException。
回答by Umesh Patnaik
We dont need a no-arg constructor while parent is serializable .
我们不需要无参数构造函数,而 parent 是可序列化的。
But when the child is serializable and not the parent we must have a no-arg const in parent to set values as required while de-serialization , but otherwise we will have default values .
但是当孩子是可序列化的而不是父母时,我们必须在 parent 中有一个 no-arg const 在反序列化时根据需要设置值,否则我们将有默认值。
回答by Neeraj
If Parent class possess the Serializable behavior then by default all child class possess the Serializable behavior.
如果父类拥有 Serializable 行为,那么默认情况下所有子类都拥有 Serializable 行为。
class Parent implements Serializable{
int x;
}
class Children extends Parent{
int m;
public static void main(String args[]){
Children c = new Children();
c.m =10;
c.x =20;
// Enter Serialization Code;
// Enter De serialization Code;
}
}
Note : When you read deserialize object, you will be able to retrieve serialize state.
注意:当您读取反序列化对象时,您将能够检索序列化状态。