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

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

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

Скажем, у вас есть человек класса, например:

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

Тогда:

Deserialize from file:

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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

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

Ответ 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 из десериализованного объекта является нулевым, поскольку он не был записан.

Ответ 9

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

Ответ 10

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

Deserialization: Чтение состояния объекта из файла/сети или где угодно. (Средняя форма файлов/поддержка сети для поддерживаемой Java-формы)