Как serialVersionUID сериализуется в Java?

Члены класса (статические) не могут быть сериализованы. Причина очевидна - они не удерживаются объектом (ами) класса. Поскольку они связаны с классом (а не с объектом этого класса), они хранятся отдельно от объекта.

serialVersionUID объявлен как статическое поле в классе, который реализует java.io.Serializable интерфейс что-то вроде следующего.

private static final long serialVersionUID = 1L;

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

Если он явно не объявлен внутри класса, реализующего Serializable интерфейс, то может выдать предупреждение.

Сериализуемый класс SomeClass не объявляет staticfinalserialVersionUID поле типа long

Это сериализовано, хотя это static как или это исключение из сериализации?

4 ответа

Решение

Сериализация выполняется "волшебным образом", с большим количеством размышлений и имеет все виды особого поведения, включая, например, поиск статического serialVersionUID класса.

Позвольте мне прояснить вам использование serialVersionUID во время записи и чтения объектов в / из файла.

В приведенном ниже коде я написал две функции writeObject() а также readObj()

writeObject() для записи объекта в файл

readObj() для чтения объекта из файла

package com.msq;

import java.io.Serializable;

public class A implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    int a;
    transient int b;

    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public int getB() {
        return b;
    }
    public void setB(int b) {
        this.b = b;
    }
}
package com.msq;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class B implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 123L ;
    /**
     * 
     */
    String name;
    A a;

    public B() {

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }

    public static void main(String[] args) {

        //writeObject();
        readObj();
    }

    static void writeObject() {
        B b = new B();
        b.setName("Musaddique");
        A a2 = new A();
        a2.setA(5);
        a2.setB(10);
        b.setA(a2);
        ObjectOutputStream write = null;

        try {
            write = new ObjectOutputStream(new FileOutputStream(
                    "D:\\serObj.bat"));
            write.writeObject(b);
            write.flush();
            write.close();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    static void readObj() {
        ObjectInputStream reader = null;

        try {
            reader = new ObjectInputStream(
                    new FileInputStream("D:\\serObj.bat"));
            B b1 = (B) reader.readObject();
            System.out.println("name: "+b1.getName());
            System.out.println("value of a: "+b1.getA().getA());
            System.out.println("value of b: "+b1.getA().getB());
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Здесь я использовал serialVersionUID = 123L для класса B и serialVersionUID = 1L для класса А, а также используется transient ключевое слово для переменной b, чтобы ограничить сохранение значения b в файл.

1) Записать данные в файл, затем прочитать файл, который вы получите после вывода

name: Musaddique
value of a: 5
value of b: 0

Вы получите значение b: 0, потому что мы использовали переходный процесс для b.

Теперь для тестирования попробуйте написать объект тем же вызовом, но во время чтения измените serialVersionUID = 765L тогда вы получите ниже исключения

java.io.InvalidClassException: com.msq.B; local class incompatible: stream classdesc serialVersionUID = 123, local class serialVersionUID = 765
    at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at com.msq.B.readObj(B.java:81)
    at com.msq.B.main(B.java:46)

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

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

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

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

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