Что означает Serializable? - PullRequest
       5

Что означает Serializable?

121 голосов
/ 07 августа 2010

Что именно означает для класса быть Serializable в Java? Или вообще, в этом отношении ...

Ответы [ 10 ]

119 голосов
/ 07 августа 2010

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

В контексте вашего вопроса, это интерфейс, который, если реализован в классе, этот класс может быть автоматически сериализован и десериализован с помощьюразные сериализаторы.

37 голосов
/ 24 августа 2015

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

Допустим, у вас есть классный человек, подобный следующему:

public class Person implements java.io.Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public String firstName;
    public String lastName;
    public int age;
    public String address;

    public void play() {
        System.out.println(String.format(
                "If I win, send me the trophy to this address: %s", address));
    }
    @Override
    public String toString() {
        return String.format(".....Person......\nFirst Name = %s\nLast Name = %s", firstName, lastName);
    }
}

и затем вы создаете объект, подобный этому:

Person william = new Person();
        william.firstName = "William";
        william.lastName = "Kinaan";
        william.age = 26;
        william.address = "Lisbon, Portugal";

Вы можете сериализовать этот объект во множество потоков.Я сделаю это для двух потоков:

Сериализация на стандартный вывод:

public static void serializeToStandardOutput(Person person)
            throws IOException {
        OutputStream outStream = System.out;
        ObjectOutputStream stdObjectOut = new ObjectOutputStream(outStream);
        stdObjectOut.writeObject(person);
        stdObjectOut.close();
        outStream.close();
    }

Сериализация в файл:

public static void serializeToFile(Person person) throws IOException {
        OutputStream outStream = new FileOutputStream("person.ser");
        ObjectOutputStream fileObjectOut = new ObjectOutputStream(outStream);
        fileObjectOut.writeObject(person);
        fileObjectOut.close();
        outStream.close();
    }

Тогда:

Десериализация из файла:

public static void deserializeFromFile() throws IOException,
            ClassNotFoundException {
        InputStream inStream = new FileInputStream("person.ser");
        ObjectInputStream fileObjectIn = new ObjectInputStream(inStream);
        Person person = (Person) fileObjectIn.readObject();
        System.out.println(person);
        fileObjectIn.close();
        inStream.close();
    }
35 голосов
/ 07 августа 2010

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

11 голосов
/ 26 апреля 2017

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

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

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

Для чего нужна сериализация?

В современной архитектуревсегда необходимо сохранить состояние объекта, а затем получить его.Например, в 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 использовался модификатор private, если это возможно, поскольку такие объявления применяются только к немедленно объявленному классу - поля serialVersionUID бесполезны в качестве унаследованных членов.

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

Если поле не сериализуемо, оно должно быть помечено как transient.Здесь мы пометили 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 из десериализованного объекта равно null , поскольку оно не было записано.

10 голосов
/ 07 августа 2010

Сериализация включает в себя сохранение текущего состояния объекта в поток и восстановление эквивалентного объекта из этого потока.Поток функционирует как контейнер для объекта

5 голосов
/ 07 августа 2010

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

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

4 голосов
/ 13 января 2012

Сериализация - это метод хранения или записи объектов и данных в файлы. Используя ObjectOutputStream и FileOutputStream классы. Эти классы имеют свои специфические методы для сохранения объектов. как writeObject();

для четкого объяснения цифрами. Подробнее см. Здесь

2 голосов
/ 25 октября 2015

Сериализация: Запись состояния объекта в файл / сеть или где-либо еще. (Имеется в виду поддерживаемая форма Java-объекта для формы, поддерживаемой файлом или формы, поддерживаемой сетью)

Десериализация: Чтение состояния объекта из файла / сети или из любого места. (Средняя форма файла / сети, поддерживаемая формой, поддерживаемой объектом Java)

2 голосов
/ 02 июня 2014

Чтобы представить с другой точки зрения. Сериализация - это своего рода интерфейс, называемый «маркерный интерфейс». Интерфейс маркера - это интерфейс, который не содержит объявлений метода, но просто обозначает (или «отмечает») класс, который реализует интерфейс как имеющий некоторая собственность. Если вы понимаете полиморфизм, это будет иметь большой смысл. В случае интерфейса маркера Serializable метод ObjectOutputStream.write (Object) завершится ошибкой, если его аргумент не реализует интерфейс. Это потенциальная ошибка в Java, это мог быть ObjectOutputStream.write (Serializable)

Настоятельно рекомендуется: чтение предмета 37 из Эффективная Java от Джошуа Блоха , чтобы узнать больше

0 голосов
/ 07 августа 2010

Просто чтобы добавить к другим ответам и в отношении общности. Сериализация иногда называется архивированием, например, в Objective-C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...