Что такое сериализация объектов?

Что подразумевается под "сериализацией объектов"? Не могли бы вы объяснить это несколькими примерами?

Ответ 1

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

Ответ 2

Вы можете рассматривать сериализацию как процесс преобразования экземпляра объекта в последовательность байтов (которая может быть двоичной или не зависит от реализации).

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

В Java механизм сериализации встроен в платформу, но вам нужно реализовать интерфейс Serializable, чтобы сделать объект сериализуемым.

Вы также можете помешать некоторым данным в вашем объекте сериализоваться, пометив атрибут как переходный.

Наконец, вы можете переопределить механизм по умолчанию и предоставить свой собственный; это может быть подходящим в некоторых особых случаях. Для этого вы используете одну из скрытых функций в java.

Важно заметить, что сериализуемое значение - это "значение" объекта или содержимого, а не определение класса. Таким образом, методы не сериализуются.

Вот очень простой пример с комментариями, чтобы облегчить его чтение:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

Когда мы запускаем эту программу, создается файл "o.ser", и мы можем видеть, что произошло.

Если мы изменим значение: someInteger на, например Integer.MAX_VALUE, мы можем сравнить результат, чтобы узнать, в чем разница.

Вот скриншот, показывающий именно эту разницу:

alt text

Можете ли вы определить различия?;)Суб >

В сериализации Java есть дополнительное релевантное поле: serialversionUID, но я думаю, что это уже слишком долго, чтобы покрыть его.

Ответ 3

Не желая отвечать на 6-летний вопрос, добавляя только очень высокий уровень понимания для людей, новых для Java

Что такое сериализация?

Преобразование объекта в байты и байты обратно в объект (десериализация).

когда используется сериализация?

Когда мы хотим сохранить объект. Когда мы хотим, чтобы объект существовал за время существования JVM.

Пример реального мира:

Банкомат: когда владелец учетной записи пытается снять деньги с сервера через банкомат, информация владельца учетной записи, такая как данные о снятии, будет сериализована и отправлена ​​на сервер, где детали будут десериализованы и использованы для выполнения операций.

Как выполняется сериализация в java.

  • Внедрить интерфейс java.io.Serializable (интерфейс маркера, чтобы не реализовывать какой-либо метод).

  • Сохранять объект: использовать класс java.io.ObjectOutputStream, поток фильтра, который является оберткой в ​​потоке байтов более низкого уровня (для записи объектов в файловые системы или переноса сплющенного объекта по сетевому проводу и перестроения на другая сторона).

    • writeObject(<<instance>>) - написать объект
    • readObject() - прочитать сериализованный объект

Помните:

Когда вы сериализуете объект, будет сохранено только состояние объекта, а не файл или методы класса объектов.

Когда вы сериализуете 2-байтовый объект, вы видите 51 байтовый сериализованный файл.

Шаги, как объект сериализуется и де-сериализуется.

Ответа на этот вопрос: Как он преобразовал файл в 51 байт?

  • Сначала записываются магические данные потока сериализации (STREAM_MAGIC = "AC ED" и STREAM_VERSION = версия JVM).
  • Затем он записывает метаданные класса, связанного с экземпляром (длина класса, имя класса, serialVersionUID).
  • Затем он рекурсивно выписывает метаданные суперкласса, пока не найдет java.lang.Object.
  • Затем начинается с фактических данных, связанных с экземпляром.
  • Наконец, записывает данные объектов, связанных с экземпляром, начиная с метаданных и заканчивая фактическим содержимым.

Если вас интересует более подробная информация о Java Serialization, проверьте эту ссылку .

Изменить: еще одна хорошая ссылка для чтения.

Это ответит на несколько частых вопросов:

  • Как не сериализовать какое-либо поле в классе.
    Ans: использование ключевого слова transient

  • Когда дочерний класс сериализуется, родительский класс получает сериализацию?
    Ans: Нет, если родитель не расширяет поля родительских интерфейсов Serializable, сериализоваться не будет.

  • Когда родитель сериализуется, класс child получает сериализацию?
    Ответ: Да, по умолчанию дочерний класс также сериализуется.

  • Как избежать генерации сериализации класса child? Ans: a. Переопределите метод writeObject и readObject и бросьте NotSerializableException.

    б. также вы можете пометить все поля, преходящие в дочернем классе.

  • Некоторые классы системного уровня, такие как Thread, OutputStream и его подклассы, и Socket не сериализуемы.

Ответ 4

Сериализация берет "живой" объект в памяти и преобразует его в формат, который может храниться где-нибудь (например, в памяти, на диске), а затем "десериализован" обратно в живой объект.

Ответ 5

Мне понравился подарок @OscarRyz. Хотя здесь я продолжаю историю сериализации, которая была первоначально написана @amitgupta.

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

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

Ученые Марса ждали полной оплаты. После того, как платеж был выполнен, ученые-марцы разделили serialversionUID с учеными Земли. Земной ученый поставил его в класс роботов, и все стало хорошо.

Ответ 6

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

Обратите внимание, что свойства объекта будут сохранены. Если вы хотите снова воскресить объект, вы должны иметь файл класса, потому что только переменные-члены будут сохранены, а не функции-члены.

например:

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

Searializable - это интерфейс маркера, который отмечает, что ваш класс сериализуем. Интерфейс маркера означает, что это просто пустой интерфейс, и использование этого интерфейса уведомит JVM о том, что этот класс можно сделать сериализуемым.

Ответ 7

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

http://en.wikipedia.org/wiki/Serialization

Ответ 8

Мои два цента из моего собственного блога:

Вот подробное объяснение сериализации: (мой собственный блог)

Сериализация:

Сериализация - это процесс сохранения состояния объекта. Он представляется и сохраняется в виде последовательности байтов. Это можно сохранить в файле. Процесс чтения состояния объекта из файла и его восстановления называется десериализацией.

Что такое сериализация?

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

Пример кода и объяснение:

Сначала рассмотрим класс Item:

public class Item implements Serializable{

    /**
    *  This is the Serializable class
    */
    private static final long serialVersionUID = 475918891428093041L;
    private Long itemId;
    private String itemName;
    private transient Double itemCostPrice;
    public Item(Long itemId, String itemName, Double itemCostPrice) {
        super();
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemCostPrice = itemCostPrice;
      }

      public Long getItemId() {
          return itemId;
      }

     @Override
      public String toString() {
          return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
       }


       public void setItemId(Long itemId) {
           this.itemId = itemId;
       }

       public String getItemName() {
           return itemName;
       }
       public void setItemName(String itemName) {
            this.itemName = itemName;
        }

       public Double getItemCostPrice() {
            return itemCostPrice;
        }

        public void setItemCostPrice(Double itemCostPrice) {
             this.itemCostPrice = itemCostPrice;
        }
}

В приведенном выше коде видно, что класс Item реализует Serializable.

Это интерфейс, который позволяет сериализуемому классу.

Теперь мы видим, что переменная с именем serialVersionUID инициализируется переменной Long. Этот номер вычисляется компилятором на основе состояния класса и атрибутов класса. Это число, которое поможет jvm идентифицировать состояние объекта при чтении состояния объекта из файла.

Для этого мы можем взглянуть на официальную документацию Oracle:

Сериализация сериализации ассоциируется с каждым сериализуемым классом a номер версии, называемый serialVersionUID, который используется во время десериализация для проверки того, что отправитель и получатель сериализованного объект загрузил классы для этого объекта, которые совместимы с в отношении сериализации. Если приемник загрузил класс для объект с другим идентификатором serialVersionUID, чем у соответствующий класс отправителя, то десериализация приведет к InvalidClassException. Сериализуемый класс может объявить о себе serialVersionUID явно, объявив поле с именем "serialVersionUID", который должен быть статическим, окончательным и длинным: ANY-ACCESS-MODIFIER статический конечный длинный serialVersionUID = 42L; Если сериализуемый класс явно не объявляет serialVersionUID, то время выполнения сериализации будет вычисляться по умолчанию serialVersionUID для этого класса на основе различных аспектов класс, как описано в сериализации объектов Java (TM) Спецификация. Однако настоятельно рекомендуется, чтобы все сериализуемые классы явно объявляют значения serialVersionUID, поскольку вычисление по умолчанию serialVersionUID очень чувствительно к классу детали, которые могут различаться в зависимости от реализаций компилятора и могут таким образом, приводят к неожиданным InvalidClassExceptions во время десериализации. Поэтому, чтобы гарантировать последовательный serialVersionUID значение в разных реализациях java-компилятора, сериализуемое класс должен объявить явное значение serialVersionUID. Это также настоятельно рекомендуется, чтобы явные объявления serialVersionUID использовали когда это возможно, так как такие объявления применяются только к сразу объявляющие классы - поля serialVersionUID не являются полезны как унаследованные.

Если вы заметили, что мы использовали другое ключевое слово, которое является временным.

Если поле не сериализуемо, оно должно быть помечено как переходное. Здесь мы пометили ItemCostPrice как переходный процесс и не хотим, чтобы он был записан в файл

Теперь давайте посмотрим, как записать состояние объекта в файл, а затем прочитать его оттуда.

public class SerializationExample {

    public static void main(String[] args){
        serialize();
       deserialize();
    } 

    public static void serialize(){

         Item item = new Item(1L,"Pen", 12.55);
         System.out.println("Before Serialization" + item);

         FileOutputStream fileOut;
         try {
             fileOut = new FileOutputStream("/tmp/item.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);
             out.writeObject(item);
             out.close();
             fileOut.close();
             System.out.println("Serialized data is saved in /tmp/item.ser");
           } catch (FileNotFoundException e) {

                  e.printStackTrace();
           } catch (IOException e) {

                  e.printStackTrace();
           }
      }

    public static void deserialize(){
        Item item;

        try {
                FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
                ObjectInputStream in = new ObjectInputStream(fileIn);
                item = (Item) in.readObject();
                System.out.println("Serialized data is read from /tmp/item.ser");
                System.out.println("After Deserialization" + item);
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        }
     }
}

В приведенном выше примере мы можем увидеть пример сериализации и десериализации объекта.

Для этого мы использовали два класса. Для сериализации объекта мы использовали ObjectOutputStream. Мы использовали метод writeObject для записи объекта в файл.

Для десериализации мы использовали ObjectInputStream, который читает из объекта из файла. Он использует readObject для чтения данных объекта из файла.

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

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]

Обратите внимание, что itemCostPrice из десериализованного объекта является нулевым, поскольку он не был записан.

Мы уже обсуждали основы Java Serialization в первой части этой статьи.

Теперь давайте обсудим это глубоко и как это работает.

Сначала начнем с serialversionuid.

serialVersionUID используется как элемент управления версиями в классе Serializable.

Если вы явно не объявляете serialVersionUID, JVM сделает это автоматически, основываясь на различных свойствах класса Serializable.

Java-алгоритм вычисления serialversionuid (Подробнее читайте здесь)

  • Имя класса.
    1. Модификаторы классов, написанные как 32-разрядное целое.
    2. Имя каждого интерфейса, отсортированного по имени.
    3. Для каждого поля класса, отсортированного по имени поля (кроме частных статических и частных полей переходных процессов: имя поля. модификаторы поля, написанные как 32-битное целое число. Дескриптор поля.
    4. Если существует инициализатор класса, выпишите следующее: Имя метода,
    5. Модификатор метода java.lang.reflect.Modifier.STATIC, написанный как 32-разрядное целое.
    6. Дескриптор метода,() V.
    7. Для каждого не-частного конструктора, отсортированного по имени метода и сигнатуре: Имя метода. Модификаторы метод, написанный как 32-битное целое число. Дескриптор метода.
    8. Для каждого не-частного метода, отсортированного по имени метода и сигнатуре: Имя метода. Модификаторы метода, написанные как 32-битное целое число. Дескриптор метода.
    9. Алгоритм SHA-1 выполняется в потоке байтов, созданных DataOutputStream, и производит пять 32-битных значений sha [0..4]. хэш-значение собирается из первого и второго 32-битных значений SHA-1. Если результат дайджест сообщения, пять 32-битные слова H0 H1 H2 H3 H4, находится в массиве из пяти значений int, названных sha, хэш-значение будет вычисляться следующим образом:
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

Алгоритм сериализации Java

Алгоритм сериализации объекта описан ниже:
1. Он записывает метаданные класса, связанного с экземпляром.
2. Он рекурсивно выписывает описание суперкласса, пока не найдет java.lang.object.
3. Как только он завершит запись информации метаданных, она начинается с фактических данных, связанных с экземпляром. Но на этот раз начинается с верхнего суперкласса.
4. Он рекурсивно записывает данные, связанные с экземпляром, начиная с наименьшего суперкласса до самого производного класса.

Что нужно иметь в виду:

  • Статические поля в классе не могут быть сериализованы.

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
    
  • Если serialversionuid отличается в классе чтения, он генерирует исключение InvalidClassException.

  • Если класс реализует сериализуемый, то все его подкласс также будут сериализованы.

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
    
  • Если класс имеет ссылку другого класса, все ссылки должны быть Serializable, иначе процесс сериализации не будет выполнен. В этом случае исключение NotSerializableException запускается во время выполнения.

Например:

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}

Ответ 9

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

Объект, который должен быть сериализован, должен реализовывать интерфейс java.io.Serializable. Механизм сериализации по умолчанию для объекта записывает класс объекта, подпись класса и значения всех непереходных и нестатических полей.

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutput интерфейс расширяет интерфейс DataOutput и добавляет методы для сериализации объектов и записи байтов в файл. ObjectOutputStream расширяет java.io.OutputStream и реализует интерфейс ObjectOutput. Он сериализует объекты, массивы и другие значения в поток. Таким образом, конструктор ObjectOutputStream записывается как:

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

Выше код использовался для создания экземпляра класса ObjectOutput с конструктором ObjectOutputStream( ), который принимает экземпляр FileOuputStream в качестве параметра.

Интерфейс ObjectOutput используется при реализации класса ObjectOutputStream. ObjectOutputStream построен для сериализации объекта.

Удаление десериализации объекта в java

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

ObjectInputStream расширяет java.io.InputStream и реализует интерфейс ObjectInput. Он десериализует объекты, массивы и другие значения из входного потока. Таким образом, конструктор ObjectInputStream записывается как:

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

Над кодом программы создается экземпляр класса ObjectInputStream для десериализации этого файла, который был сериализован классом ObjectInputStream. Вышеприведенный код создает экземпляр, используя экземпляр класса FileInputStream, который содержит указанный объект файла, который должен быть десериализован, потому что конструктор ObjectInputStream() нуждается в потоке ввода.

Ответ 10

Сериализация - это процесс превращения объекта Java в массив байтов, а затем обратно в объект с сохраненным состоянием. Полезно для различных вещей, таких как отправка объектов по сети или кеширование вещей на диск.

Подробнее из эта короткая статья, в которой достаточно хорошо объясняется часть процесса процесса, а затем перейдите к Serializable javadoc. Вы также можете быть заинтересованы в чтении этого связанного вопроса.

Ответ 11

Вернуть файл как объект: http://www.tutorialspoint.com/java/java_serialization.htm

        import java.io.*;

        public class SerializeDemo
        {
           public static void main(String [] args)
           {
              Employee e = new Employee();
              e.name = "Reyan Ali";
              e.address = "Phokka Kuan, Ambehta Peer";
              e.SSN = 11122333;
              e.number = 101;

              try
              {
                 FileOutputStream fileOut =
                 new FileOutputStream("/tmp/employee.ser");
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
                 out.writeObject(e);
                 out.close();
                 fileOut.close();
                 System.out.printf("Serialized data is saved in /tmp/employee.ser");
              }catch(IOException i)
              {
                  i.printStackTrace();
              }
           }
        }

    import java.io.*;
    public class DeserializeDemo
    {
       public static void main(String [] args)
       {
          Employee e = null;
          try
          {
             FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             e = (Employee) in.readObject();
             in.close();
             fileIn.close();
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
          }
          System.out.println("Deserialized Employee...");
          System.out.println("Name: " + e.name);
          System.out.println("Address: " + e.address);
          System.out.println("SSN: " + e.SSN);
          System.out.println("Number: " + e.number);
        }
    }

Ответ 12

Java Сериализация объектов

введите описание изображения здесь

Serialization - это механизм преобразования графика объектов Java в массив байтов для хранения (to disk file) или передача (across a network). Используя механизм десериализации, мы можем восстановить графики объектов. Графики объектов восстанавливаются правильно, используя механизм обмена ссылками. Но перед сохранением его statcheckcheck weather serialVersionUID формирует файл ввода файла/сети и .class файл serialVersionUID одинаковы. если не выбрасывать java.io.InvalidClassException.

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

serialVersionUID Синтаксис

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

serialVersionUID должен быть в процессе сериализации. Но разработчик может добавить его в исходный файл java. Если вы не добавите его в исходный файл java, сериализация будет генерировать serialVersionUID и связать его с классом. Сериализованный объект будет содержать этот serialVersionUID вместе с другими данными.

Примечание. Настоятельно рекомендуется, чтобы все сериализуемые классы явно объявляли значения serialVersionUID, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, и поэтому могут приводить к непредвиденным конфликтам serialVersionUID во время десериализации, что приводит к десериализации потерпеть неудачу.

Проверка сериализуемых классов

введите описание изображения здесь


Объект Java является сериализуемым. если класс или любой из его суперклассов реализует либо интерфейс java.io.Serializable или его субинтерфейс, java.io.Externalizable.

  • Класс должен реализовывать java.io.Serializable интерфейс, чтобы успешно сериализовать его объект. Serializable является интерфейсом маркера и используется для информирования компилятора о том, что класс, реализующий его, должен быть добавлен сериализуемым поведением. Здесь виртуальная машина Java (JVM) отвечает за ее автоматическую сериализацию.

    переходное ключевое слово: java.io.Serializable interface

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

    • Поля, объявленные как переходные или статические, игнорируются процессом сериализации.

    TRANSIENT и VOLATILE

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
    
  • Реализация интерфейса Externalizable позволяет объекту принимать полный контроль над содержимым и форматом сериализованной формы объекта. Методы интерфейса Externalizable, writeExternal и readExternal вызываются для сохранения и восстановления состояния объектов. Когда они реализуются классом, они могут писать и читать собственное состояние, используя все методы ObjectOutput и ObjectInput. Объекты должны обрабатывать любые версии, которые происходят.

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
    
  • Только объекты, поддерживающие интерфейс java.io.Serializable или java.io.Externalizable, могут быть written to / read from потоками. Класс каждого сериализуемого объекта кодируется, включая имя класса и подпись класса, значения полей объекта и массивов и закрытие любых других объектов, на которые ссылаются исходные объекты.

Сериализуемый пример для файлов

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Сериализуемый пример через сеть

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

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@see

Ответ 13

Я нашел этот хороший ответ от здесь: -

Представьте, что вы хотите сохранить состояние одного или нескольких объектов. Если у Java не было сериализации, вам нужно использовать один из классов ввода-вывода для записи состояния переменных экземпляра всех объектов, которые вы хотите сохранить. Хуже всего будет пытаться восстановить новые объекты, которые были практически идентичны тем объектам, которые вы пытались сохранить. Вам нужен собственный протокол для того, как вы написали и восстановили состояние каждого объекта, или вы могли бы установить переменные с неправильными значениями. Например, представьте, что вы сохранили объект с переменными экземпляра для высоты и веса. В то время, когда вы сохраняете состояние объекта, вы можете записать высоту и вес как два ints в файле, но порядок, в котором вы их пишете, имеет решающее значение. Было бы слишком легко воссоздать объект, но смешивать значения высоты и веса - используя сохраненную высоту в качестве значения для нового веса объектов и наоборот. Цель сериализации - помочь нам достичь любого сложного сценария, который мы просто наблюдали в более простой форме.

Работа с ObjectOutputStream и ObjectInputStream

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

ObjectOutputStream.writeObject() - serialize and write

ObjectInputStream.readObject() - read and deserialize

Классы java.io.ObjectOutputStream и java.io.ObjectInputStream считаются классами более высокого уровня в пакете java.io, и, как мы узнали в предыдущей главе, это означает, что вы обернете их вокруг классов более низкого уровня, таких как java.io.FileOutputStream и java.io.FileInputStream. Heres небольшая программа, которая создает объект, сериализует его, а затем десериализует его:

import java.io.*;

class Car implements Serializable { } // 1

public class SerializeCar {
public static void main(String[] args) {
Car c = new Car(); // 2
try {
FileOutputStream fs = new FileOutputStream("testSer.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(c); // 3
os.close();
} Catch (Exception e) { e.printStackTrace(); }

try {
FileInputStream fis = new FileInputStream("testSer.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
c = (Car) ois.readObject(); // 4
ois.close();
} Catch (Exception e) { e.printStackTrace(); }
}
}

Давайте рассмотрим ключевые моменты в этом примере:

  • Мы заявляем, что класс Car реализует интерфейс Serializable. Serializable - интерфейс маркера; у него нет методов для реализации.

  • Мы создаем новый объект Car, который, как мы знаем, сериализуем.

  • Мы сериализуем объект Car c, вызывая метод writeObject(). Во-первых, мы должны были поместить весь наш код, связанный с I/O, в блок try/Catch. Затем нам нужно было создать FileOutputStream для записи объекта. Затем мы завернули FileOutputStream в ObjectOutputStream, который является классом с магическим методом сериализации, который нам нужен. Помните, что вызов writeObject() выполняет две задачи: он сериализует объект, а затем записывает сериализованный объект в файл.

  • Мы де-сериализуем объект Car, вызывая метод readObject(). Метод readObject() возвращает объект, поэтому мы должны отбросить десериализованный объект обратно на автомобиль. Опять же, нам пришлось пройти через типичные обручи ввода-вывода, чтобы настроить это. - Подробнее

Ответ 14

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

Ответ 15

Сериализация (из объекта)

В контексте хранения и передачи данных сериализация представляет собой процесс преобразования структуры данных или состояния объекта в формат, который может быть сохранен (например, в буфере файла или памяти или передан по линии сетевого соединения) и "воскрешенные" (де-сериализованные) позже в той же или другой компьютерной среде.

Ответ 16

Этот вопрос также может помочь вам понять отзыв о Serialization:

Что будет не так, если мы сделаем все java-объекты Serializable Так как Serializable - это пустой interface и Java обеспечивает надежную сериализацию после добавления инструментов Serializable - почему они не сделали все сериализуемым и что это?

Ответ можно найти по адресу Почему Java требует интерфейс Serializable?", который описывает это, может привести к проблемам безопасности, а также к разрыву инкапсуляции.

Ответ 17

| * | Сериализация класса: преобразование объекта в байты и байты обратно в объект (десериализация).

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

| = > Object-Serialization - это процесс преобразования состояния объекта в пар байтов.

  • | → Реализовать, когда вы хотите, чтобы объект существовал за пределами жизни JVM.
  • | → Serilized Object может быть сохранен в базе данных.
  • | → Serializable-obects не могут быть прочитаны и поняты людьми, чтобы мы могли добиться безопасности.

| = > Object-Deserialization - это процесс получения состояния объекта и хранения его в объекте (java.lang.Object).

  • | → Перед сохранением своего состояния он проверяет информацию о формате serialVersionUID формы ввода файла/сети и .class файл serialVersionUID одинаковы.
    & nbsp & nbspIf не бросать java.io.InvalidClassException.

| = > Объект Java является сериализуемым, если его класс или любой его суперкласс -

  • реализует интерфейс java.io.Serializable или
  • его subinterface, java.io.Externalizable.

| = > Статические поля в классе не могут быть сериализованы.

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

| = > Если вы не хотите сериализовать переменную класса, используйте ключевое слово transient

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

| = > Если класс реализует сериализуемый, тогда все его подкласс также будут сериализованы.

| = > Если класс имеет ссылку другого класса, все ссылки должны быть Serializable, иначе процесс сериализации не будет выполнен. В этом случае исключение NotSerializableException запускается во время выполнения.