Java 静态变量是否在序列化过程中序列化
我无意中理解了java序列化。我在许多文档和书籍中读到,静态和瞬态变量不能在Java中序列化。 我们声明一个serialVersionUid,如下所示Java 静态变量是否在序列化过程中序列化,java,Java,我无意中理解了java序列化。我在许多文档和书籍中读到,静态和瞬态变量不能在Java中序列化。 我们声明一个serialVersionUid,如下所示 private static final long serialVersionUID = 1L; 如果静态变量没有序列化,那么在反序列化过程中,我们经常会遇到异常 java.io.InvalidClassException 从反序列化对象中提取SerialVersionId,并与加载类的SerialVersionId进行比较 据我所知,我认为
private static final long serialVersionUID = 1L;
如果静态变量没有序列化,那么在反序列化过程中,我们经常会遇到异常
java.io.InvalidClassException
从反序列化对象中提取SerialVersionId,并与加载类的SerialVersionId进行比较
据我所知,我认为如果静态变量不能序列化。这一例外毫无意义。我可能错了,因为我还在学习
“java中的静态和瞬态变量无法序列化”是一个神话吗。请纠正我的错误,我对这个概念感到困惑。
serialVersionUID
是特殊的,不受这些规则的约束。序列化机制中有专门处理此字段以执行自动版本检查的代码。serialVersionUID是一个特殊的静态变量,用于验证本地类是否与用于序列化对象的类兼容。与其他变量一样,它不仅仅是一个静态变量,这些变量肯定不是序列化的
当一个类的对象第一次被序列化时,一个包含类名和序列版本UID的类描述符被写入流中。反序列化时,JVM检查从流中读取的串行版本UID是否与本地类的UID相同。如果不是,它甚至不会尝试反序列化对象,因为它知道类是不兼容的
瞬态
变量未序列化,因此在反序列化过程中,这些变量将使用相应的默认值初始化(例如:对于对象null
,int
0
)下面的示例解释了静态、实例、瞬态和超类变量序列化及其输出。 序列化类:
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
超级类:
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
序列化和反序列化:
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
输出:
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
您可以自己测试—下面是一些示例代码,可以回答您的问题:
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
的对象,其中包含一个静态整型字段和一个非静态字段。我们序列化对象,然后在序列化之后增加静态整数
当我们稍后反序列化对象时,我们看到它的值是递增的,这意味着它没有被序列化。在本例中,
serialVersionUID
也被序列化
在类初始化期间提供值的任何静态变量都被序列化
但是,在正常情况下,不会序列化在主类/运行时向静态变量提供值的情况
您可以通过将其公开并在反序列化后尝试访问来尝试访问serialVersionUID
有关详细信息,请参阅“”
希望有帮助。干杯 否,如果类具有静态变量,则在序列化时将跳过该变量。因为静态变量对于所有对象都是唯一的,而序列化仅用于保存对象属性(对象的状态)。
静态变量是类的属性是,如果在声明时初始化静态变量,则静态变量将被序列化 比如说, 案例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
}
}
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
}
}
输出:
//after deserialization
firstName= abc
lastName= null
案例2:在声明时初始化
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
}
}
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
}
}
输出:
//after deserialization
firstName= abc
lastName= null
//反序列化后
firstName= abc
lastName= pqr
声明时初始化的任何静态变量都将被序列化。特殊静态变量是什么意思?它意味着它是一个特殊的静态变量。(特别是,它在序列化中的处理方式与其他静态变量不同。)它很特殊,因为序列化机制查找此静态变量以了解类的串行版本UID是什么。序列化机制忽略了所有其他静态变量。感谢您给出的精确答案,请欣赏。静态变量属于一个类,而不属于任何单个实例。序列化的概念与对象的当前状态有关。只有与类的特定实例关联的数据才被序列化,因此在序列化过程中会忽略静态成员字段。“因此,在反序列化时,将从类中加载静态变量值。(将加载当前值)。”如果类在另一个JVM中反序列化,该怎么办?@mdev:正确的说法是,
static
变量根本不被触及。说“静态变量值将从类加载”到它本身是没有意义的。静态变量不会被序列化,无论它在类初始化期间是否提供了值。您引用的来源和答案都不正确,您的ci