如何在自定义序列化(Java)中覆盖最终的writeObject()方法

时间:2018-04-13 15:05:59

标签: java serialization override private final

我正在学习自定义序列化,我不明白如何覆盖2个方法writeObject()和readObject(),因为我知道这2个方法是最终的,我知道最后的方法不能被覆盖

来自ObjectOutputStream的

writeObject()方法:

public final void writeObject(Object obj) throws IOException

writeObject()需要像这里一样被覆盖:

private void writeObject(ObjectOutputStream output) throws IOException

我理解新的writeObject()方法是私有的,但是使用Java序列化机制的反射来调用它。但我不明白如何覆盖最终方法。

帐户类:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Account implements Serializable {

    private static final long serialVersionUID = 154754873L;
    String userName = "durga";
    transient String psw = "anushka";

    private void writeObject(ObjectOutputStream output) throws IOException {

        output.defaultWriteObject();
        output.writeObject(psw);
    }

    private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {

        input.defaultReadObject();
        psw = (String) input.readObject();
    }
}

SerializationDemo类:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializationDemo {

    public void serialize(Account a1, String fileName) {

        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {

            oos.writeObject(a1); 

        } catch (FileNotFoundException ex) {

            System.out.printf("ERROR: %s", ex);

        } catch (IOException ex) {

            System.out.printf("ERROR: %s", ex);
        }
    }

    public Account deserialize(String fileName) {

        Account a2 = null;

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("account.ser"))) {

            a2 = (Account) ois.readObject();
        } catch (FileNotFoundException ex) {

            System.out.printf("ERROR: %s", ex);

        } catch (IOException | ClassNotFoundException ex) {

            System.out.printf("ERROR: %s", ex); 
        }

        return a2;
    }
}

SerializationApp类:

public class SerializationApp {

    public static void main(String args[]) {

        Account a1 = new Account();

        System.out.println(a1.userName + " " + a1.psw);

        SerializationDemo demo = new SerializationDemo();

        demo.serialize(a1, "account.ser"); 

        Account a2 = demo.deserialize("account.ser");

        System.out.println(a2.userName + " " + a2.psw);
    }
}

2 个答案:

答案 0 :(得分:1)

你很困惑。

  1. ObjectOutputStream.writeObject()final,您无法覆盖它。
  2. 您可以用于自定义序列化的private void writeObject(ObjectOutput)方法进入自己的 Serializable类,而不是扩展到ObjectOutputStream的类。不会出现覆盖的问题。

答案 1 :(得分:0)

无法覆盖final方法。

但你不需要。

自定义序列化的一种方法是提供writeObjectreadObject方法(就像您一样):

private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

请注意,我们不会在此讨论实现或覆盖方法。

这应该足够了 - 我想知道为什么你需要覆盖writeObject中的ObjectOutputStream

如果要通过继承ObjectOutputStream来自定义序列化,您仍然可以“覆盖”对象的写入方式。为此,子类ObjectOutputStream,在子类中调用super()并覆盖writeObjectOverride。如果您调用受保护的ObjectOutputStream()构造函数,则enableOverride标记设置为true,最终方法writeObject(您无法覆盖)委托给{{1} }(可以覆盖)。