在Java中,序列化其实有两个用处,保存和传送数据。
保存数据:将对象的状态持久保存在存储媒体(数据库或文件系统)上,以后可以重新创建精确的副本。
Java允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,也就是说,如果JVM停止了,原本占用的内存被释放,对象自然也不复存在。如果要求在JVM停止运行之后能够保存指定的对象,并在将来重新读取被保存的对象,Java对象序列化就能够实现。使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,以后如果要用到这个对象,就可以通过反序列化,将这些字节组装成对象。注意,对象序列化保存的是对象的"状态",即它的成员变量,而静态变量属于类的状态,由此可知,对象序列化不会关注类中的静态变量。
传送数据:将对象从一个应用程序域发送到另一个应用程序域中(远程调用RMI)。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象,而不是通过构造方法新建一个新的对象再赋予原来的值。将对象转化为流的过程其实就是序列化(Serialization),而将流重新转化成对象的过程则是反序列化(Deserialization)。
下面是序列化对象信息:
public class Person implements Serializable
{
private static final long serialVersionUID = 1L;
private int age;
private String name;
public Person(String name, int age)
{
this.age = age;
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Override
public String toString()
{
return "Person [ name = " + name + ", age = " + age + " ]";
}
}
上面代码有: private static final long serialVersionUID = 1L;
这个序列化ID的作用是用来决定是否可以反序列化。如果有两个类,都实现了Serializable,且功能代码完全一致,一个负责序列化,另一个负责反序列化,如果两者的序列化ID不同,那么不能相互序列化和反序列化。
public class Test
{
public static void main(String[] args)
{
write();
read();
}
private static void write()
{
Person student = new Person("shawn", 18);
try
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("seria.txt"));
out.writeObject(student); //
System.out.println("Object has been written.");
out.close();
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
private static void read()
{
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("seria.txt"));
Person studentRead = (Person) in.readObject();
System.out.println("Object is:");
System.out.println(studentRead);
in.close();
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}