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

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

16 ответов

Решение

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

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

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

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

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

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

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

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

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

// This class implements "Serializable" to let the system know
// it's 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, мы можем сравнить выходные данные, чтобы увидеть, в чем разница.

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

альтернативный текст

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

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

Смел ответить на 6-летний вопрос, добавив только очень высокий уровень понимания для людей, плохо знакомых с Ja va

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

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

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

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

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

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

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

  1. Воплощать в жизнь java.io.Serializable интерфейс (маркерный интерфейс, поэтому нет способа реализовать).

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

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

Помните:

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

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

Действия по сериализации и десериализации объекта.

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

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

Если вы заинтересованы в дополнительной информации о сериализации Ja va, перейдите по этой ссылке.

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

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

  1. Как не сериализовать ни одно поле в классе.
    Ответ: используйте временное ключевое слово

  2. Когда дочерний класс сериализуется, родительский класс сериализуется?
    Ответ: Нет, если родительский объект не расширяет Serializable интерфейс, родительское поле не сериализуется.

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

  4. Как предотвратить сериализацию дочернего класса?
    Ответ: а. Переопределите метод writeObject и readObject и бросьте NotSerializableException,

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

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

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

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

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

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

Ученые Марса ждали полной оплаты. Как только оплата была произведена, ученые Марса поделились серийной версией UID с учеными Земли. Ученый Земли установил класс роботов, и все стало хорошо.

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

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

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

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

Зачем нужна сериализация?

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

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

Сначала давайте посмотрим на класс предметов:

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:

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

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

Если поле не сериализуемо, оно должно быть помечено как временное. Here we marked the itemCostPrice as transient and don't want it to be written in a file

Now let's have a look on how to write the state of an object in the file and then read it from there.

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();
        }
     }
}

In the above we can see an example of serialization and deserialization of an object.

For that we used two classes. For serializing the object we have used ObjectOutputStream. We have used the method writeObject to write the object in the file.

For Deserializing we have used ObjectInputStream which reads from the object from the file. It uses readObject to read the object data from the file.

The output of the above code would be like:

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]

Notice that itemCostPrice from deserialized object is null as it was not written.

We have already discussed the basics of Java Serialization in part I of this article.

Now let's discuss it deeply and how it works.

First let's start with the serialversionuid.

The serialVersionUID is used as a version control in a Serializable class.

If you do not explicitly declare a serialVersionUID, JVM will do it for you automatically, based on various properties of the Serializable class.

Java's Algorithm of Calculating serialversionuid (Read more details here)

  1. The class name.
    1. The class modifiers written as a 32-bit integer.
    2. The name of each interface sorted by name.
    3. For each field of the class sorted by field name (except private static and private transient fields: The name of the field. The modifiers of the field written as a 32-bit integer. The descriptor of the field.
    4. If a class initializer exists, write out the following: The name of the method,.
    5. The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
    6. The descriptor of the method, ()V.
    7. For each non-private constructor sorted by method name and signature: The name of the method,. The modifiers of the method written as a 32-bit integer. The descriptor of the method.
    8. For each non-private method sorted by method name and signature: The name of the method. The modifiers of the method written as a 32-bit integer. The descriptor of the method.
    9. The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and produces five 32-bit values sha[0..4]. The hash value is assembled from the first and second 32-bit values of the SHA-1 message digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named sha, the hash value would be computed as follows:
    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's serialization algorithm

The algorithm to serialize an object is described as below:
1. It writes out the metadata of the class associated with an instance.
2. It recursively writes out the description of the superclass until it finds java.lang.object.
3. Once it finishes writing the metadata information, it then starts with the actual data associated with the instance. But this time, it starts from the topmost superclass.
4. It recursively writes the data associated with the instance, starting from the least superclass to the most-derived class.

Things To Keep In Mind:

  1. Static fields in a class cannot be serialized.

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
    
  2. If the serialversionuid is different in the read class it will throw a InvalidClassException исключение.

  3. If a class implements serializable then all its sub classes will also be serializable.

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
    
  4. If a class has a reference of another class, all the references must be Serializable otherwise serialization process will not be performed. In such case, NotSerializableException is thrown at runtime.

Например:

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

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

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

например:

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

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

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

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

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

Serialization представляет собой механизм для преобразования графа Java-объектов в массив байтов для хранения (to disk file) или передача (across a network), то с помощью десериализации мы можем восстановить граф объектов. Графики объектов корректно восстанавливаются с помощью механизма разделения ссылок. Но перед сохранением проверьте, совпадают ли 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. Если serialVersionUID не включен, среда выполнения сериализации сгенерирует 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 предотвратит сериализацию этого элемента данных.

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

    Переходный и изменчивый

    +--------------+--------+-------------------------------------+
    |  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();
    }
}

@увидеть

Сериализация - это процесс сохранения объекта на носителе данных (например, файла или буфера памяти) или передачи его по сетевому соединению в двоичной форме. Сериализованные объекты независимы от 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() Конструктор нуждается во входном потоке.

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

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

Верните файл как объект: 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);
        }
    }

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

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

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

  • | -> Реализуйте, когда вы хотите, чтобы объект существовал вне времени жизни JVM.
  • | -> Сериализованный объект может храниться в базе данных.
  • | -> Сериализуемые объекты не могут быть прочитаны и поняты людьми, поэтому мы можем добиться безопасности.

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

  • | -> Перед сохранением своего состояния он проверяет, совпадают ли входной файл / сеть serialVersionUID с файлом serialVersionUID и файл.class.
    Если не сгенерировать исключение java.io.InvalidClassException.

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

  • реализует либо интерфейс java.io.Serializable, либо
  • его подинтерфейс, 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;
}

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

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

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

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

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

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

В Java то же самое достигается с помощью интерфейсов сериализации и экстернализации.

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

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