当前位置: 首页 > 知识库问答 >
问题:

如何在自定义序列化(Java)中重写final writeObject()方法

樊桐
2023-03-14

我正在学习自定义序列化,但我不明白如何超越writeObject()和readObject()这两个方法,因为我知道这两个方法是final,并且我知道final方法不能被重写。

来自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个答案

赵雅懿
2023-03-14

你很困惑。

  1. ObjectOutputStream。writeObject()是最终的,不能重写它
于鸿博
2023-03-14

无法重写final方法。

但你不需要。

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

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

注意,这里我们不讨论实现或重写方法。

这实际上已经足够了-我想知道为什么需要在ObjectOutputStream中重写writeObject。

如果要通过子类化ObjectOutputStream来自定义序列化,仍然可以“重写”对象的编写方式。为此,在子类调用super()和重写writeObjectOverride中,使用子类ObjectOutputStream。如果调用受保护的ObjectOutputStream()构造函数,则enableOverride标志设置为true,并且最后的方法writeObject(无法重写)委托给writeObjectOverride(可以重写)。

 类似资料:
  • 问题内容: 我有一个对象,其中包含一些要序列化的不可序列化字段。它们来自我无法更改的单独API,因此使它们可序列化不是一种选择。主要问题是Location类。它包含我需要的四个可以序列化的东西,所有整数。如何使用read / writeObject创建可以执行以下操作的自定义序列化方法: 我怎样才能做到这一点? 问题答案: Java支持自定义序列化。阅读“自定义默认协议”部分。 去引用: 但是,有

  • 我有一门狗和猫的课,看起来像这样: 这些类都实现了我创建的一个名为Speakable的接口,它看起来像这样: 这个Speakable接口之所以存在,是因为我需要一个引用变量,允许我将狗和猫添加到同一个ArrayList中,并且仍然在它们上调用说话()方法。 我还需要重写Comparable接口的compareTo()方法,以便比较狗的名字。调用此方法时,我认为我的代码如下所示:a.compareT

  • 我在一个Kafka消息中使用了我自己的类,它有一堆字符串数据类型。 我想我需要编写自己的序列化器并将其提供给生产者属性?

  • 问题内容: 我有两个要使用Jackson序列化为JSON的Java类: 我想将Item序列化为此JSON: 用户序列化为仅包含。我还将能够将所有用户对象序列化为,例如: 所以我想我需要为此编写一个自定义的序列化程序并尝试过: 我使用来自的以下代码对JSON进行了序列化: 但是我得到这个错误: 如何在Jackson上使用自定义序列化程序? 这就是我对Gson的处理方式: 但是我现在需要和Jackso

  • 问题内容: 我想将某些类型为ParentClass的字段作为json字符串存储到我的数据库中。我不想使用Serializable接口和DataType.SERIALIZABLE导致它与序列化类的完整类名相关联。 所以我正在使用以下代码: 持久性类的一种: 这是我遇到的两个问题: 我没有得到如何指定从对象到字符串的自定义转换的信息。似乎ORMLite调用Object.toString()以获得对象的

  • 问题内容: 序列化器很少,例如 我们如何创建自己的自定义序列化程序? 问题答案: 在这里,您有一个示例,将自己的序列化器/解串器用于Kafka消息值。对于Kafka消息密钥是同一回事。 我们希望将MyMessage的序列化版本作为Kafka值发送,并再次将其反序列化为使用方的MyMessage对象。 在生产者端序列化MyMessage。 您应该创建一个实现org.apache.kafka.comm