1.首先定义一个学生类
public class Student implements Serializable {
/**
* 这个序列化ID的生成由该类的成员所共同决定
* 该类的成员将来如果发生变化,其对应的ID也会发生变化,所以一般我们需要固定ID,即在类的定义时就赋予它一个默认值
*/
private static final long serialVersionUID = 1L;
private String name ;
private int age ;
static String country = "中国";
transient String password = "12345";
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
}
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;
}
}
2.然后再使用对象流来操作对象
/*
ObjectInputStream 称为反序列化流,利用输入流从文件中读取对象
ObjectOutputStream 称为 序列化流,利用输出流向文件中写入对象
特点:用于操作对象。可以将对象写入到文件中,也可以从文件中读取对象。
只能将支持 java.io.Serializable 接口的对象写入流中
由于反序列化流一次只能读取一个对象,当读到文件末尾时,会抛出Exception in thread "main" java.io.EOFException
当 Serialization 运行时检测到某个类具有以下问题之一时,抛出此异常。
该类的序列版本号与从流中读取的类描述符的版本号不匹配
该类包含未知数据类型
该类没有可访问的无参数构造方法
如何解决对象输入流读取对象出现异常的问题呢?
思路:将所有对象封装成一个对象就能解决问题
分析:集合也可以看作是一个对象,将我们所用到的对象都存进这个集合,再通过对集合来调用
*/
public class ObjectDemo {
public static void main(String[] args) throws IOException, IOException,
ClassNotFoundException {
storeMethod();
loadMethod();
}
// 将文件中的对象读取到程序中
private static void loadMethod() throws IOException, FileNotFoundException,
ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"object.txt"));
Object object = ois.readObject();
ArrayList<Student> list = (ArrayList<Student>) object;
// 遍历list集合
for (Student student : list) {
System.out.println(student.getName() + "---" + student.getAge());
}
}
// 将对象写入到文件
private static void storeMethod() throws IOException, FileNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"object.txt"));
List<Student> list = new ArrayList<Student>();
list.add(new Student("张三", 20));
list.add(new Student("李四", 20));
list.add(new Student("王五", 20));
oos.writeObject(list);
oos.close();
}
}
3.序列化
/*
*
Serializable是一个序列化,标记型接口,只起标记作用;
被static修饰的成员变量,不能序列化(因为它存在于方法区的静态区中,不随对象的转移而转移)
被transient(瞬态)修饰的成员变量,也不能序列化
transient的作用:
然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等)
,为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。
换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
*/
public class ObjectDemo2 {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("mm.txt"));
oos.writeObject(new Student("张三",20));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("mm.txt"));
Object object = ois.readObject();
Student stu = (Student)object;
System.out.println(stu.getName() + "--" + stu.getAge()
+ "--" + stu.country + "--" + stu.password);
}
}
/*
* 张三--20--中国--null
* (1)为什么被static修饰的变量也会被读出来?
* “中国”根本没有被写入到文件中,而是一直存在于方法区中
* (2)为什么password是null?
* 因为被transient修饰的变量不能被序列化,即不能通过流来操作,最后输出的只能是默认初始值
*/