Подтвердить что ты не робот

Сериализуются статические переменные в процессе сериализации

Я наткнулся на понимание сериализации Java. Во многих документах и ​​книгах я прочитал, что статические и переходные переменные не могут быть сериализованы в Java.  Мы объявляем serialVersionUid следующим образом.

private static final long serialVersionUID = 1L;

Если статическая переменная не была сериализована, мы часто сталкиваемся с исключением в процессе де-сериализации.

java.io.InvalidClassException

в котором serialVersionUID из десериализованного объекта извлекается и сравнивается с serialVersionUID загруженного класса.

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

  • Переменные экземпляра: Эти переменные сериализуются, поэтому во время десериализации мы возвращаем сериализованное состояние.

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

  • переходные переменные: transient переменные не сериализуются, поэтому при десериализации эти переменные будут инициализированы соответствующими значениями по умолчанию (например: для объектов null, int 0).

  • Переменные суперкласса: Если суперкласс также реализовал интерфейс Serializable, тогда эти переменные будут сериализованы, иначе он не будет сериализовать переменные суперкласса. и при десериализации JVM будет запускать конструктор по умолчанию в суперклассе и заполняет значения по умолчанию. То же самое произойдет для всех суперклассов.

Ответ 3

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

Ответ 4

В этом случае также сериализуется serialVersionUID.

Сериализуется любая статическая переменная, которая предоставляется во время инициализации класса.

Однако в обычных случаях, когда вы указываете значение статической переменной в главном классе/времени выполнения, не будет сериализовано.

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

Вы можете обратиться к http://javabeginnerstutorial.com/core-java-tutorial/transient-vs-static-variable-java/" для получения дополнительной информации.

Надеюсь, что это поможет. Приветствия!

Ответ 5

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

Сериализованный класс:

public class SerializeEx extends SuperSerializeEx implements Serializable {

    private static final long serialVersionUID = 1L;
    public static int staticNumber = 1234;
    public int instanceNumber = 1234;

    public SerializeEx() {
        staticNumber = 0;
        instanceNumber = 0;
        System.out.println("---sub class constructor---");
    }

    public SerializeEx(int staticNumber, int instanceNumber, int superNumber) {
        super(superNumber);
        this.staticNumber = staticNumber;
        this.instanceNumber = instanceNumber;
    }
}

Суперкласс:

public class SuperSerializeEx {

    public int superNumber;

    public SuperSerializeEx() {
        System.out.println("---super class constructor---");
        this.superNumber = 1000;
    }

    public SuperSerializeEx(int superNumber) {
        this.superNumber = superNumber;
    }
}

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

public class MainSerialization {

    public static void main(String[] args) {
        String fileName = "testing.txt";
        serialize(fileName);
        deSerialize(fileName);
    }

    public static void serialize(String fileName) {
        System.err.println("Serialize.....");
        SerializeEx serializeMe = new SerializeEx(10, 10, 10);
        FileOutputStream fos = null;
        ObjectOutputStream out = null;
        try {
            fos = new FileOutputStream(fileName);
            out = new ObjectOutputStream(fos);
            out.writeObject(serializeMe);
            out.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void deSerialize(String fileName) {
        System.err.println("DeSerialize.....");
        SerializeEx time = null;
        FileInputStream fis = null;
        ObjectInputStream in = null;
        try {
            fis = new FileInputStream(fileName);
            in = new ObjectInputStream(fis);
            time = (SerializeEx) in.readObject();
            in.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        System.err.println("Instance Numer = " + time.instanceNumber + " \tStatic Number= " + time.staticNumber + " \t Super Number= " + time.superNumber);
        SerializeEx serializeMe = new SerializeEx(1001, 1001, 1001); //Modifying the static and instnce variables
        System.err.println("Instance Numer = " + time.instanceNumber + " \tStatic Number= " + time.staticNumber + " \t Super Number= " + time.superNumber);
    }
}

Вывод:

---super class constructor---
Serialize.....
DeSerialize.....
Instance Numer = 10     Static Number= 10      Super Number= 1000
Instance Numer = 10     Static Number= 1001    Super Number= 1000

Ответ 6

Вы можете проверить это сами - вот пример кода, который должен ответить на ваш вопрос:

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;

class TestJava implements Serializable{
  public static int k = 10;
  public int j = 5;

  public static void main(String[] args) {

    TestJava tj1= new TestJava();
    TestJava tj2;

        try{ //serialization
            FileOutputStream fos = new FileOutputStream("myclass.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(tj1);
            oos.close();
            fos.close();
            System.out.println("object serielized 1..."+tj1.j);
            System.out.println("object serielized 2..."+tj1.k);
            System.out.println("object serielized 3..."+k);
            k=++k; // 'k' value incrementd after serialization
          } catch(FileNotFoundException fnfe){
             fnfe.printStackTrace();
          } catch(IOException ioex){
             ioex.printStackTrace();
          }

          try{ //deserialization
              FileInputStream fis = new FileInputStream("myclass.ser");
              ObjectInputStream ois = new ObjectInputStream(fis);
              tj2 = (TestJava) ois.readObject();
              ois.close();
              fis.close();
              System.out.println("object DEEEEserielized 1..."+tj2.j);
              System.out.println("object DEEEEserielized 2..."+tj2.k); 
              System.out.println("object DEEEEserielized 3..."+k); 
            // in deserialization 'k' value is shown as incremented. 
            // That means Static varialbe 'K' is not serialized.
            // if 'K' value is serialized then, it has to show old value before incrementd the 'K' value.
            } catch(FileNotFoundException fnfe){
              fnfe.printStackTrace();
            } catch(IOException ioex){
              ioex.printStackTrace();
            } catch(ClassNotFoundException CNFE){
              CNFE.printStackTrace();                   
           }
      }
}

Это выведет следующее:

object serielized 1...5
object serielized 2...10
object serielized 3...10
object DEEEEserielized 1...5
object DEEEEserielized 2...11
object DEEEEserielized 3...11

Поэтому мы создаем объект класса TestJava с одним статическим целочисленным полем и одним нестатическим полем. Мы сериализуем объект, затем - после сериализации - увеличиваем статическое целое число.

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

Ответ 7

Нет, если класс имеет статическую переменную, то во время сериализации эта переменная будет пропущена. потому что статическая переменная уникальна для всего объекта, а сериализация используется только для сохранения свойств объекта (состояния объекта). static variable - свойство класса

Ответ 8

Да, статическая переменная будет сериализована, если она будет инициализирована во время объявления.

Например,

случай 1: без инициализации на момент объявления

class Person implements Serializable{

  public String firstName;

  static  String lastName;  
}

public class Employee {

  public static void main(String[] args) {

      Person p = new Person();
      p.firstName="abc";
      p.lastName="xyz";
      //to do serialization

  }

}

выход:

//after deserialization

 firstName= abc

 lastName= null

случай 2: с инициализацией во время объявления

class Person implements Serializable{

  public String firstName=="abc";

  static  String lastName="pqr";  
}

public class Employee {

  public static void main(String[] args) {

      Person p = new Person();
      p.firstName="abc";
      p.lastName="xyz";
      //to do serialization

  }

 }

выход:

//после десериализации

firstName= abc

lastName= pqr

Ответ 9

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