Вопрос-ответ

What is the difference between Serializable and Externalizable in Java?

В чем разница между Serializable и Externalizable в Java?

В чем разница между Serializable и Externalizable в Java?

Переведено автоматически
Ответ 1

В дополнение к другим ответам, реализуя java.io.Serializable, вы получаете возможность "автоматической" сериализации для объектов вашего класса. Не нужно реализовывать какую-либо другую логику, она просто будет работать. Среда выполнения Java будет использовать отражение, чтобы выяснить, как маршалировать и отменять маршалирование ваших объектов.

В более ранней версии Java отражение было очень медленным, и поэтому сериализация графов больших объектов (например, в клиент-серверных приложениях RMI) была небольшой проблемой с производительностью. Чтобы справиться с этой ситуацией, был предоставлен java.io.Externalizable интерфейс, аналогичный java.io.Serializable, но с написанными на заказ механизмами для выполнения функций маршалинга и демаршалинга (вам нужно реализовать методы readExternal и writeExternal в вашем классе). Это дает вам возможность обойти узкое место производительности отражения.

В последних версиях Java (разумеется, начиная с версии 1.3) производительность отражения значительно выше, чем раньше, и поэтому это является гораздо меньшей проблемой. Я подозреваю, что вам было бы трудно получить значимую выгоду от Externalizable использования современной JVM.

Кроме того, встроенный механизм сериализации Java не единственный, вы можете получить сторонние замены, такие как сериализация JBoss, которая значительно быстрее и является заменой по умолчанию.

Большим недостатком Externalizable является то, что вам приходится поддерживать эту логику самостоятельно - если вы добавляете, удаляете или изменяете поле в своем классе, вам приходится изменять свои методы writeExternal/readExternal, чтобы учитывать это.

Подводя итог, Externalizable это пережиток времен Java 1.1. В этом действительно больше нет необходимости.

Ответ 2

Сериализация предоставляет функциональность по умолчанию для сохранения и последующего воссоздания объекта. Он использует подробный формат для определения всего графика объектов, которые будут сохранены, например, предположим, что у вас есть LinkedList и вы кодируете, как показано ниже, тогда сериализация по умолчанию обнаружит все связанные объекты и будет сериализована. При сериализации по умолчанию объект создается полностью из его сохраненных битов, без вызовов конструктора.

  ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("/Users/Desktop/files/temp.txt"));
oos.writeObject(linkedListHead); //writing head of linked list
oos.close();

Но если вы хотите ограниченную сериализацию или не хотите, чтобы какая-то часть вашего объекта сериализовалась, тогда используйте Externalizable . Интерфейс Externalizable расширяет интерфейс Serializable и добавляет два метода, writeExternal() и readExternal() . Они автоматически вызываются при сериализации или десериализации. При работе с Externalizable мы должны помнить, что конструктор по умолчанию должен быть общедоступным, иначе код вызовет исключение. Пожалуйста, следуйте приведенному ниже коду:

public class MyExternalizable implements Externalizable
{

private String userName;
private String passWord;
private Integer roll;

public MyExternalizable()
{
}

public MyExternalizable(String userName, String passWord, Integer roll)
{
this.userName = userName;
this.passWord = passWord;
this.roll = roll;
}

@Override
public void writeExternal(ObjectOutput oo) throws IOException
{
oo.writeObject(userName);
oo.writeObject(roll);
}

@Override
public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException
{
userName = (String)oi.readObject();
roll = (Integer)oi.readObject();
}

public String toString()
{
StringBuilder b = new StringBuilder();
b.append("userName: ");
b.append(userName);
b.append(" passWord: ");
b.append(passWord);
b.append(" roll: ");
b.append(roll);

return b.toString();
}
public static void main(String[] args)
{
try
{
MyExternalizable m = new MyExternalizable("nikki", "student001", 20);
System.out.println(m.toString());
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/Desktop/files/temp1.txt"));
oos.writeObject(m);
oos.close();

System.out.println("***********************************************************************");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/Desktop/files/temp1.txt"));
MyExternalizable mm = (MyExternalizable)ois.readObject();
mm.toString();
System.out.println(mm.toString());
}
catch (ClassNotFoundException ex)
{
Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
}
catch(IOException ex)
{
Logger.getLogger(MyExternalizable.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Здесь, если вы прокомментируете конструктор по умолчанию, код выдаст приведенное ниже исключение:

 java.io.InvalidClassException: javaserialization.MyExternalizable;     
javaserialization.MyExternalizable; no valid constructor.

Мы можем заметить, что поскольку пароль является конфиденциальной информацией, поэтому я не сериализую его в методе writeExternal(ObjectOutput oo) и не устанавливаю значение same в readExternal(ObjectInput oi). Именно такую гибкость обеспечивает Externalizable .

Вывод приведенного выше кода выглядит следующим образом:

userName: nikki  passWord: student001  roll: 20
***********************************************************************
userName: nikki passWord: null roll: 20

Мы можем наблюдать, поскольку мы не устанавливаем значение passWord, поэтому оно равно null.

Того же самого можно добиться, объявив поле пароля временным.

private transient String passWord;

Надеюсь, это поможет. Приношу извинения, если допустил какие-либо ошибки. Спасибо.

Ответ 3

Ключевые различия между Serializable и Externalizable


  1. Интерфейс маркера: Serializable это интерфейс маркера без каких-либо методов. Externalizable интерфейс содержит два метода: writeExternal() и readExternal().

  2. Процесс сериализации: определенный программистом процесс сериализации будет запущен для классов, реализующих Externalizable интерфейс.

  3. Обслуживание: Несовместимые изменения могут нарушить сериализацию.


Несовместимые изменения в классах - это те изменения, для которых гарантия совместимости не может быть сохранена, например, удаление полей и т.д.



  1. Обратная совместимость: если вам нужно поддерживать несколько версий, вы можете полностью контролировать Externalizable интерфейс. Вы можете поддерживать разные версии вашего объекта.

  2. открытый конструктор без аргументов: Serializable использует отражение для построения объекта и не требует конструктора без аргументов. Но Externalizable требует открытого конструктора без аргументов.

Ответ 4

Сериализация использует определенное поведение по умолчанию для сохранения и последующего воссоздания объекта. Вы можете указать, в каком порядке или как обрабатывать ссылки и сложные структуры данных, но в конечном итоге все сводится к использованию поведения по умолчанию для каждого примитивного поля данных.

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

java serialization