Java中带继承的对象序列化

作者: Arvin Chen 分类: Java 来源: Break易站(www.breakyizhan.com)
  •   Java 面向对象/Java 继承

    Java中带继承的对象序列化

    序列化是一种将对象状态转换为字节流的机制。反序列化是相反的过程,其中字节流用于在内存中重新创建实际的Java对象。

    有一些关于继承的序列化情况:

    情况1:如果超类是可序列化的,那么子类是可自动序列化的:如果超类是可序列化的,那么默认情况下每个子类都是可序列化的。因此,即使子类没有实现Serializable接口(如果它的超类实现了Serializable),那么我们也可以序列化子类对象。

    // Java program to demonstrate 
    // that if superclass is
    // serializable then subclass 
    // is automatically serializable
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    // superclass A 
    // implementing Serializable interface
    class A implements Serializable
    {
    	int i;
    	
    	// parameterized constructor
    	public A(int i) 
    	{
    		this.i = i;
    	}
    	
    }
    
    // subclass B 
    // B class doesn't implement Serializable
    // interface.
    class B extends A
    {
    	int j;
    	
    	// parameterized constructor
    	public B(int i, int j) 
    	{
    		super(i);
    		this.j = j;
    	}
    }
    
    // Driver class
    public class Test
    {
    	public static void main(String[] args) 
    			throws Exception 
    	{
    		B b1 = new B(10,20);
    		
    		System.out.println("i = " + b1.i);
    		System.out.println("j = " + b1.j);
    		
    		/* Serializing B's(subclass) object */
    		
    		//Saving of object in a file
    		FileOutputStream fos = new FileOutputStream("abc.ser");
    		ObjectOutputStream oos = new ObjectOutputStream(fos);
    			
    		// Method for serialization of B's class object
    		oos.writeObject(b1);
    			
    		// closing streams
    		oos.close();
    		fos.close();
    			
    		System.out.println("Object has been serialized");
    		
    		/* De-Serializing B's(subclass) object */
    		
    		// Reading the object from a file
    		FileInputStream fis = new FileInputStream("abc.ser");
    		ObjectInputStream ois = new ObjectInputStream(fis);
    			
    		// Method for de-serialization of B's class object
    		B b2 = (B)ois.readObject();
    			
    		// closing streams
    		ois.close();
    		fis.close();
    			
    		System.out.println("Object has been deserialized");
    		
    		System.out.println("i = " + b2.i);
    		System.out.println("j = " + b2.j);
    	}
    }
    

    输出:

    i = 10
    j = 20
    Object has been serialized
    Object has been deserialized
    i = 10
    j = 20

    Java中带继承的对象序列化

    如果超类不是可序列化的,那么子类仍然可以被序列化:即使超类没有实现Serializable接口,如果子类本身实现了Serializable接口,我们也可以序列化子类对象。所以我们可以说为了序列化子类对象,超类不需要可序列化。但是在这种情况下,序列化过程中超类的实例会发生什么。以下过程解释了这一点。

     

    当一个类是可序列化的,但它的超类不是时会发生什么?

    • 序列化:在序列化时,如果任何实例变量继承自不可序列化的超类,那么JVM将忽略该实例变量的原始值并将缺省值保存到文件中。
    • 反序列化:在反序列化时,如果存在任何不可序列化的超类,那么JVM将在超类中执行实例控制流。为了在类中执行实例控制流,JVM将始终调用该类的默认(无参数)构造函数。所以每个不可序列化的超类必须包含默认的构造函数,否则我们会得到运行时异常。
    // Java program to demonstrate 
    // the case if superclass need
    // not to be serializable 
    // while serializing subclass 
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;;
    
    // superclass A 
    // A class doesn't implement Serializable
    // interface.
    class A 
    {
    	int i;
    	
    	// parameterized constructor
    	public A(int i) 
    	{
    		this.i = i;
    	}
    	
    	// default constructor
    	// this constructor must be present
    	// otherwise we will get runtime exception
    	public A()
    	{
    		i = 50;
    		System.out.println("A's class constructor called");
    	}
    	
    }
    
    // subclass B 
    // implementing Serializable interface
    class B extends A implements Serializable
    {
    	int j;
    	
    	// parameterized constructor
    	public B(int i,int j) 
    	{
    		super(i);
    		this.j = j;
    	}
    }
    
    // Driver class
    public class Test
    {
    	public static void main(String[] args) 
    			throws Exception 
    	{
    		B b1 = new B(10,20);
    		
    		System.out.println("i = " + b1.i);
    		System.out.println("j = " + b1.j);
    		
    		// Serializing B's(subclass) object 
    		
    		//Saving of object in a file
    		FileOutputStream fos = new FileOutputStream("abc.ser");
    		ObjectOutputStream oos = new ObjectOutputStream(fos);
    			
    		// Method for serialization of B's class object
    		oos.writeObject(b1);
    			
    		// closing streams
    		oos.close();
    		fos.close();
    			
    		System.out.println("Object has been serialized");
    		
    		// De-Serializing B's(subclass) object 
    		
    		// Reading the object from a file
    		FileInputStream fis = new FileInputStream("abc.ser");
    		ObjectInputStream ois = new ObjectInputStream(fis);
    			
    		// Method for de-serialization of B's class object
    		B b2 = (B)ois.readObject();
    			
    		// closing streams
    		ois.close();
    		fis.close();
    			
    		System.out.println("Object has been deserialized");
    		
    		System.out.println("i = " + b2.i);
    		System.out.println("j = " + b2.j);
    	}
    }
    

    输出:

    i = 10
    j = 20
    Object has been serialized
    A's class constructor called
    Object has been deserialized
    i = 0
    j = 20

    Java中带继承的对象序列化

    如果超类是可序列化的,但我们不希望子类被序列化:没有直接的方法来阻止java中的子类进行序列化。程序员可以通过在子类中实现writeObject()和readObject()方法来实现这一点,并且需要从这些方法中抛出NotSerializableException异常。这些方法分别在序列化和反序列化过程中执行。通过重写这些方法,我们只是实现了我们自己的定制序列化。

    // Java program to demonstrate 
    // how to prevent 
    // subclass from serialization
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.NotSerializableException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    // superclass A 
    // implementing Serializable interface
    class A implements Serializable
    {
    	int i;
    	
    	// parameterized constructor
    	public A(int i) 
    	{
    		this.i = i;
    	}
    	
    }
    
    // subclass B 
    // B class doesn't implement Serializable
    // interface.
    class B extends A
    {
    	int j;
    	
    	// parameterized constructor
    	public B(int i,int j) 
    	{
    		super(i);
    		this.j = j;
    	}
    	
    	// By implementing writeObject method, 
    	// we can prevent
    	// subclass from serialization
    	private void writeObject(ObjectOutputStream out) throws IOException
    	{
    		throw new NotSerializableException();
    	}
    	
    	// By implementing readObject method, 
    	// we can prevent
    	// subclass from de-serialization
    	private void readObject(ObjectInputStream in) throws IOException
    	{
    		throw new NotSerializableException();
    	}
    	
    }
    
    // Driver class
    public class Test
    {
    	public static void main(String[] args) 
    			throws Exception 
    	{
    		B b1 = new B(10, 20);
    		
    		System.out.println("i = " + b1.i);
    		System.out.println("j = " + b1.j);
    		
    		// Serializing B's(subclass) object 
    		
    		//Saving of object in a file
    		FileOutputStream fos = new FileOutputStream("abc.ser");
    		ObjectOutputStream oos = new ObjectOutputStream(fos);
    			
    		// Method for serialization of B's class object
    		oos.writeObject(b1);
    			
    		// closing streams
    		oos.close();
    		fos.close();
    			
    		System.out.println("Object has been serialized");
    		
    		// De-Serializing B's(subclass) object 
    		
    		// Reading the object from a file
    		FileInputStream fis = new FileInputStream("abc.ser");
    		ObjectInputStream ois = new ObjectInputStream(fis);
    			
    		// Method for de-serialization of B's class object
    		B b2 = (B)ois.readObject();
    			
    		// closing streams
    		ois.close();
    		fis.close();
    			
    		System.out.println("Object has been deserialized");
    		
    		System.out.println("i = " + b2.i);
    		System.out.println("j = " + b2.j);
    	}
    }
    

    输出:

    i = 10
    j = 20
    Exception in thread "main" java.io.NotSerializableException
    	at B.writeObject(Test.java:44)
  •   Java 面向对象/Java 继承
  •   本文标题:Java中带继承的对象序列化 - Break易站
    转载请保留页面地址:https://www.breakyizhan.com/java/4249.html
      微信返利机器人
      免费:淘宝,京东,拼多多优惠券
      腾讯,爱奇艺,优酷的VIP视频免费解析,免费看
      即刻扫描二维码,添加微信机器人!

    发表笔记

    电子邮件地址不会被公开。 必填项已用*标注