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


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

10 107

10 ответов:

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

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

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

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

допустим, у вас есть класс человек, как следующее:

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

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

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

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

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

в чем необходимость Сериализация?

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

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

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

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

среда выполнения сериализации связывается с каждым сериализуемым классом a номер версии, называемый serialVersionUID, который используется во время десериализация для проверки того, что отправитель и получатель сериализованного объект имеет загруженные классы для этого объекта, которые совместимы с уважение к сериализации. Если получатель загрузил класс для объект, который имеет другой serialVersionUID, чем у объекта соответствующий класс отправителя, то десериализация приведет к InvalidClassException. Сериализуемый класс может объявить свой собственный serialVersionUID явно путем объявления поля с именем "serialVersionUID", что должен быть статическим, окончательным и типа long: Любой-доступ-модификатор статические заключительные долго serialVersionUID = 42Л; если сериализуемый класс явно не объявляет 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 от десериализованного объекта null как это не было написано.

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

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

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

для четкой эксплантации с цифрами . см. здесь для получения дополнительной информации

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

настоятельно рекомендуется: чтение пункта 37 из эффективная Java от Joshua Bloch чтобы узнать больше.

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

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

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