您的位置:首页 > 编程语言 > Java开发

Java序列化学习笔记

2011-03-11 14:18 295 查看
     Java 对象序列化为二进制文件的技术是 Java 系列技术中一个较为重要的技术点,在大多数情况下,只需要了解被序列化的类需要实现 Serializable 接口,使用 ObjectInputStream 和 ObjectOutputStream 进行序列化和反序列化即可。

     在工作中,经常会碰到序列化的情况,因为我们调用的东西不可能都在本地,往往需要通过RMI,一些远程接口调用。这样数据序列化的技术更显得重要。而java序列化技术为我们实现这些远程调用提供了技术保障。

 

一. 序列化的ID,请看如下代码

片段一:

 

public class Person implements Serializable{
private static final long serialVersionUID = 1L;
private int age;

private String name;

private String mobile;

private transient String address;  //不被序列化的属性
}
 

片段二:

public class Person implements Serializable{
private static final long serialVersionUID = 2L;
private int age;

private String name;

private String mobile;

private transient String address;  //不被序列化的属性
}
 

两个类除了serialVersionUID,其余完全一样,但这两个类是不能被序列化与反序列化的,所以在写程序时,实现了序列化的类,serialVersionUID一定要一致,否则客户端与服务端将不匹配,会因serialVersionUID不匹配导致意想不到的问题。当然也可以通过服务端强制更新serialVersionUID值,让客户端主动报错,来强制更新程序。

 

二.子类实现Serializable接口,而父类并没有实现Serializable 接口

父类:Person.java

/**
* Created on 2011-3-11
* @author         shixing_11@sina.com
* @version        1.0
*/
public class Person {
private int age;

private String name;

private String mobile;

private transient String address;  //不被序列化的属性

public Person(){
System.out.println("父类没有实现序列化接口时,默认构造器会被调用");
}

public Person(String name,int age){
this.name = name;
this.age = age;
}

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;
}
public String getMobile(){
return mobile;
}
public void setMobile(String mobile){
this.mobile = mobile;
}

public void setAddress(String address) {
this.address = address;
}

public String getAddress(){
return address;
}

}
 

子类:Student.java

/**
* Created on 2011-3-11
* @author shixing_11@sina.com
* @version        1.0
*/
public class Student extends Person implements Serializable
{
public Student(String name, int age){
super(name, age);
}
private static final long serialVersionUID = 1L;

public static String S_T = "static属性不能被序列化";

private int no;

private String schoolName;

public void setSchoolName(String schoolName){
this.schoolName = schoolName;
}

public String getSchoolName(){
return schoolName;
}

public void setNo(int no){
this.no = no;
}

public int getNo(){
return no;
}
}
 

做如下测试:

/**
* Created on 2011-3-11
* @author shixing_11@sina.com
* @version        1.0
*/
public class SerializeTest
{
public static void main(String[] args){
Student student = new Student("shixing_11",27);
student.setMobile("1515808XXXX");  //父类的属性
student.setAddress("浙江省杭州市"); //父类的属性
student.setNo(1111111);   //子类自有属性
student.setSchoolName("XX理工大学"); //子类自有属性
serializeObject(student);  //序列化方法
Student.S_T = "我是static,我的值被改";
deSerializeObject();   //反序列化
}

private static void deSerializeObject() {
try{
InputStream is = new FileInputStream("C://ss.ser");
ObjectInputStream ois = new ObjectInputStream(is);
Student student = (Student)ois.readObject();
ois.close();
System.out.println(Student.S_T);
System.out.println(student.getNo());
System.out.println(student.getSchoolName());
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
public static void serializeObject(Person person){
try{
OutputStream os = new FileOutputStream("C://ss.ser");
ObjectOutputStream ois = new ObjectOutputStream(os);
ois.writeObject(person);
ois.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}
 

运行结果:



结论: 

 

1. 声明为 transient 型的属性是不被序列化的。

2. S_T属性的值被改变了,本来是序列时保存进去的是"static属性不能被序列化“,但读出来发现该值被改变,说明static声明的属性并没有     被写进文件里,所以声明为static型的属性是不被序列化的。

3. 子类实现Serializable接口,父类未实现Serializable接口,反序列化时父类的属性会被恢复成原始值,即int 0 ,String null.

    父类必须有无参的构造方法,因为如果父类实现了Serializable接口,则会直接从序列化过的文件里反序列化,读出来原来的对象即可,

    但若父类没有实现Serializable接口,则无法直接读取,所以只有调父类的默认构造器创建出该类的对象,再进行属性填充。

 

三.父类实现了Serializable接口的情况较简单,只需记住规则,如果父类实现了Serializable接口,则子类默认也可被序列化,不需要显式声明Serializable接口。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息