Класс, который реализует Serializable, должен реализовывать некоторые методы?

Я знаю, что 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 маркерным интерфейсом?

4 ответа

Да, Serializable - это маркерный интерфейс. Только классы, которые требуют специальной обработки, должны реализовывать эти методы.

Иными словами, вы можете реализовать один или несколько из этих методов, чтобы настроить способ сериализации или десериализации экземпляров класса. Обычно это не требуется, поскольку поведение по умолчанию является адекватным для большинства потребностей.

Эти методы используются для настройки процесса сериализации. Я приведу вам пример.

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 при сериализации полей, что не будет делать метод сериализации по умолчанию.

Это просто. Если вы хотите настраиваемую сериализацию, вы предоставляете вышеупомянутые методы в классе, который нужно сериализовать.

Пример: если вы сериализуете User.java, предоставьте в этом классе следующие методы для настраиваемой сериализации: private void writeObject(java.io.ObjectOutputStream out) выбрасывает IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

В любом случае, когда вы вызываете сериализацию объекта через objectOutputStream.writeObject (объект, который в данном случае является пользователем), элемент управления будет автоматически перенаправлен в метод writeObject объекта User.java.

Если вы не предоставите методы в User.java. Тогда процесс идет по умолчанию.

Примечание: если вы предоставляете реализацию writeObject/readObject для обоих классов в сериализуемом классе, то работает только настраиваемая сериализация, в противном случае она использует маршрут по умолчанию. Надеюсь это поможет!

Я приведу здесь дикую догадку о причине. Учитывая тот факт, что вы можете использовать теги для определения того, какие поля сериализуемы, я сначала подумал, что внутренняя работа сериализации, например, в ObjectOutputStream, сделаны через отражение.

Так что, может быть, writeObject Метод на самом деле также проверяет, существует ли закрытый метод с той же сигнатурой, определенной для объекта, и вызывает его, если он есть. В конце концов, тот же метод уже использует рефлексию, позволяющую определить, какое поле сериализовать и как, поэтому проверка наличия специального метода - это не большие затраты, я считаю...

Это может показаться немного странным, но звучит как приличное решение. Принудительная реализация в интерфейсе была бы слишком большой, поскольку большую часть времени это обычное явление. Использование абстрактного класса было бы невозможным в модели наследования Singe, такой как Java. C# использует атрибуты (эквивалент @ аннотации на Java).

Надеюсь, что кто-то с большим знанием может пролить больше света на это.:)

Другие вопросы по тегам