Java对象的序列化与反序列化(1)
(1)序列化和反序列化的概念
序列化:将对象通过IO流的操作保存到文本文件(对象转换为字节序列的过程)
反序列化:将文本文件的内容,通过IO流的形式读入程序(将字节序列转换为对象的过程)
!注意!:
1、序列化只是类的属性被序列化,其方法或构造方法不会被序列化。
2、关键字transient定义的属性是属于临时属性,是不会做jvm默认的序列化工作的。
(2)该类中需要涉及到的类或接口有:
1、Serializable (interface):可序列化的接口,此方法里面是没有抽
象的方法,只是一个标准和规范。在需要序列化的
类当中实现这个类,然后其创建的对象就可以实现序列化的操作。
2、ObjectOutputStream(OutputStream()):在ObjectOutputStream()的参数OutputStream()可以建立一个FileStream(文件目录【写出文件】),以目标文件的文件目录作为输出的目标文件而创建对象的输出流。
3、ObjectInputStream(InputStream()):在ObjectInputStream()的参数InputStream()可以建立一个FileStream(文件目录【读入文件】),以读入文件作为源文件而创建对象的输入流。
(3)所涉及到的常用方法:
1、ObjectOutputStream:
writeObject(参数);参数=“
实现了Serializable接口的类的对象
”,向输出流中写入对象
Flush():输出流刷新
close():关闭流
2、ObjectInputStream:
readObject(): 向输入流中读取对象,因为读取的是Object对象,需要强制装换成“实现了Serializable接口的类的对象”
close():关闭流。
(4)代码块:
public class Student implements Serializable{
/**
* 该Student类实现了Serializable接口,说明该类可以被序列化。
*/
private static final long serialVersionUID = 1L;
private int id;
private String name;
private int age;
public Student(){}
public Student(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
主类代码:
序列化:将对象保存到了“D:/Serializable.dat”中
public class SerializableTest {
public static void main(String[] args){
Student student=new Student(1000,"zhansgna",32);
try {
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("D:/Serializable.dat"));<span style="color:#6633ff;">//以D:/Serializable.dat文件作为目标输出文件,创建输出流对象。</span>
out.writeObject(student);<span style="color:#3333ff;">//将实现了Serializable接口的对象Student类的对象写入输出流。</span>
out.flush();<span style="color:#000099;">//刷新输出流</span>
out.close();<span style="color:#000099;">//关闭输出流</span>
} catch (Exception e) {
e.printStackTrace();
}
}
}
反序列化:将“D:/Serializable.dat”中的读取对象
public class SerializableTest {
public static void main(String[] args){
Student student=new Student(1000,"zhansgna",32);
try {
ObjectInputStream ind=new ObjectInputStream(
new FileInputStream("D:/Serializable.dat"));//<span style="color: rgb(102, 51, 255); font-family: Arial, Helvetica, sans-serif;">以D:/Serializable.dat文件作为源文件,创建输入流对象。</span>
Student stu1=(Student) ind.readObject();<span style="color:#330099;">//读取文件中的对象,因为读取的对象是Object类型的,需要强制装换为Student类型</span>
System.out.println(stu1);<span style="color:#330099;">//调用Student类的toString方法。</span>
ind.close();<span style="color:#000099;">//关闭流。</span>
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果一个属性被transient定义的话,是不会做jvm默认序列化操作,但是可以自己定义序列化操作:方法就是:
public class Student implements Serializable{
/**
* 该Student类实现了Serializable接口,说明该类可以被序列化。
*/
private static final long serialVersionUID = 1L;
private int id;
private String name;
private <span style="color:#ff0000;">transient</span> int age;
public Student(){}
public Student(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
}
<span style="font-family: Arial, Helvetica, sans-serif;"><u><em><strong><span style="color:#ff0000;">//自己定义序列化操作</span></strong></em></u></span><span style="white-space:pre"> </span><pre><span style="white-space:pre"> </span>private void readObject(java.io.ObjectInputStream stream)
<span style="white-space:pre"> </span> throws IOException, ClassNotFoundException{
//对jvm默认序列化得元素进行序列化
stream.defaultReadObject();
//对age进行序列化操作
this.age=stream.readInt();
} private void writeObject(java.io.ObjectOutputStream stream) throws IOException{
<span></span><pre><span style="white-space:pre"> </span>//对jvm默认序列化得元素进行序列化
stream.defaultWriteObject();//age自己进行序列化stream.writeInt(age);
}
}
总结:在本次的实验当中如何对一个对象进行序列化和反序列化的操作,这个好处就是在于可以将所定义到的对象,保存到文件当中,也可以随时进行调用。
当对象的某一个属性被transient修饰的时候,不会做JVM默认的序列化,但是可以自己定义序列化操作,也是很方便的。