序列化是一种将对象状态转换为字节流的机制。反序列化是使用字节流在内存中重新创建实际Java对象的反向过程。此机制用于持久化对象。
创建的字节流与平台无关。因此,在一个平台上序列化的对象可以在另一个平台上反序列化。
为了使Java对象可序列化,我们实现 JAVA伊奥。可序列化 界面 ObjectOutputStream类包含 writeObject() 方法序列化对象。
public final void writeObject(Object obj) throws IOException
ObjectInputStream类包含 readObject() 方法来反序列化对象。
public final Object readObject() throws IOException, ClassNotFoundException
序列化的优点 1.保存/保存对象的状态。 2.通过网络传送对象。
只有那些正在实现的类的对象才能被序列化 JAVA伊奥。可序列化 界面 Serializable是一个 标记接口 (没有数据成员和方法)。它用于“标记”java类,以便这些类的对象可以获得某些功能。标记接口的其他示例包括:-可克隆和远程。
要记住的要点 1.如果父类实现了可序列化接口,则子类不需要实现它,反之亦然。 2.通过序列化过程只保存非静态数据成员。 3.静态数据成员和瞬态数据成员不通过序列化过程保存。所以,如果您不想保存非静态数据成员的值,请将其设置为瞬态。 4.当对象被反序列化时,永远不会调用对象的构造函数。 5.关联对象必须实现可序列化接口。 例子:
class A implements Serializable{ // B also implements Serializable // interface. B ob=new B(); }
SerialVersionUID 序列化运行时将版本号与每个可序列化类(称为SerialVersionUID)相关联,该类在反序列化期间用于验证序列化对象的发送方和接收方是否为该对象加载了与序列化兼容的类。如果接收方为对象加载的类的UID与相应发送方的类的UID不同,则反序列化将导致 InvalidClassException .可序列化类可以通过声明字段名显式声明自己的UID。 它必须是静态的、最终的和长类型的。 i、 e——任意访问修饰符静态最终长serialVersionUID=42L;
如果可序列化类没有显式声明serialVersionUID,则序列化运行时将根据类的各个方面计算该类的默认值,如Java对象序列化规范中所述。但是,强烈建议所有可序列化类显式声明serialVersionUID值,因为其计算对类细节高度敏感,这些细节可能因编译器实现而异,类中的任何更改或使用不同的id都可能会影响序列化数据。
还建议对UID使用private修饰符,因为它不可用作继承成员。
连载机 serialver是JDK附带的工具。它用于获取Java类的SerialVersionID号。 可以运行以下命令来获取serialVersionUID
serialver[-classpath classpath][show][classname…]
例1:
// Java code for serialization and deserialization // of a Java object import java.io.*; class Demo implements java.io.Serializable { public int a; public String b; // Default constructor public Demo( int a, String b) { this .a = a; this .b = b; } } class Test { public static void main(String[] args) { Demo object = new Demo( 1 , "geeksforgeeks" ); String filename = "file.ser" ; // Serialization try { //Saving of object in a file FileOutputStream file = new FileOutputStream(filename); ObjectOutputStream out = new ObjectOutputStream(file); // Method for serialization of object out.writeObject(object); out.close(); file.close(); System.out.println( "Object has been serialized" ); } catch (IOException ex) { System.out.println( "IOException is caught" ); } Demo object1 = null ; // Deserialization try { // Reading the object from a file FileInputStream file = new FileInputStream(filename); ObjectInputStream in = new ObjectInputStream(file); // Method for deserialization of object object1 = (Demo)in.readObject(); in.close(); file.close(); System.out.println( "Object has been deserialized " ); System.out.println( "a = " + object1.a); System.out.println( "b = " + object1.b); } catch (IOException ex) { System.out.println( "IOException is caught" ); } catch (ClassNotFoundException ex) { System.out.println( "ClassNotFoundException is caught" ); } } } |
输出:
Object has been serialized Object has been deserialized a = 1 b = geeksforgeeks
例2:
// Java code for serialization and deserialization // of a Java object import java.io.*; class Emp implements Serializable { private static final long serialversionUID = 129348938L; transient int a; static int b; String name; int age; // Default constructor public Emp(String name, int age, int a, int b) { this .name = name; this .age = age; this .a = a; this .b = b; } } public class SerialExample { public static void printdata(Emp object1) { System.out.println( "name = " + object1.name); System.out.println( "age = " + object1.age); System.out.println( "a = " + object1.a); System.out.println( "b = " + object1.b); } public static void main(String[] args) { Emp object = new Emp( "ab" , 20 , 2 , 1000 ); String filename = "shubham.txt" ; // Serialization try { // Saving of object in a file FileOutputStream file = new FileOutputStream (filename); ObjectOutputStream out = new ObjectOutputStream (file); // Method for serialization of object out.writeObject(object); out.close(); file.close(); System.out.println( "Object has been serialized" + "Data before Deserialization." ); printdata(object); // value of static variable changed object.b = 2000 ; } catch (IOException ex) { System.out.println( "IOException is caught" ); } object = null ; // Deserialization try { // Reading the object from a file FileInputStream file = new FileInputStream (filename); ObjectInputStream in = new ObjectInputStream (file); // Method for deserialization of object object = (Emp)in.readObject(); in.close(); file.close(); System.out.println( "Object has been deserialized" + "Data after Deserialization." ); printdata(object); // System.out.println("z = " + object1.z); } catch (IOException ex) { System.out.println( "IOException is caught" ); } catch (ClassNotFoundException ex) { System.out.println( "ClassNotFoundException" + " is caught" ); } } } |
输出:
Object has been serialized Data before Deserialization. name = ab age = 20 a = 2 b = 1000 Object has been deserialized Data after Deserialization. name = ab age = 20 a = 0 b = 2000
输出说明: 您已经看到,在反序列化对象时,a和b的值发生了变化。原因是a标记为瞬态,b标记为静态。 万一 瞬态变量:- 在序列化过程中,未序列化使用transient关键字定义的变量。反序列化期间,此变量将使用默认值初始化。(例如:对于对象,它是null,对于int,它是0)。 万一 静态变量:- 在序列化过程中,使用static关键字定义的变量不会序列化。在反序列化过程中,将使用类中定义的当前值加载此变量。
本文由 Mehak Narang和Shubham Juneja .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。