Java基础笔记(2):序列化和反序列化
(一)序列化和反序列化
- 序列化/反序列化的作用
- 将Java中的对象以字节的形式永久保存在硬盘中
- 字节形式的对象方便在网络中传送
- 实现序列化的类
- 必须实现Serializable(Externalizable)接口
- 拥有serialVersionUID(static final long类型,是类的序列化版本号)
- 对象序列化的方式(对象->字节形式)
- 首先创建一个ObjectOutputStream对象,构造器参数是一个FileOutputStream输出流对象
- 比如ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File(“F://Customer.txt”)));
- 然后使用ObjectOutputStream的writeObject()方法将对象以十六进制的形式写进文件
- 对象反序列化的方式(字节形式->对象)
- 首先创建一个ObjectInputStream对象,构造器参数是一个FileInputStream输入流对象
- 比如ObjectInputStream oi = new ObjectInputStream(new FileInputStream((new File(“F://Customer.txt”))));
- 然后使用ObjectInputStream的readObject()方法从文件中读取字节转换为对象
- serialVersionUID的作用
- 为了保证反序列化的对象和目标对象相同,如果serialVersionUID不同会抛出java.io.InvalidClassException异常
(二)流处理
- 流处理让数据可以在文件和程序之间传输,也可以让程序之间传输数据
- java.io包流处理
- 字节流:一个字节一个字节来读
- 字符流 :一个字符一个字符来读,一个字符==两个字节
- FileInputStream的read()方法是字节流读取,所以对于读入的中文并不能正确显示
- 中文只是不能显示但并不影响复制,使用FileInputStream读取文件,然后使用FileOutputStream作为输出流,输出的文本中文正常
- FileReader和FileWriter()是按照字符来处理读入输出,所以中文能够正常显示,对应的也是read()和write()方法
(三)super关键词
- super关键词的用法
- 使用super.属性值可以访问父类的非private类型域
- 使用super.方法名可以调用父类的非private方法
- 对于构造器,可以直接使用super()调用父类构造器
- 对于子类,创建对象的时候会包含一个父类的对象,使用super引用这个对象,使用this引用子类自身的属性
class SuperClass{
protected int value;
public SuperClass(int value){
this.value = value;
}
}
class SubClass extends SuperClass{
private int value;
public SubClass(){
super(300);
System.out.println(super.value);
}
}
public class TestSuper {
public static void main(String[] args){
SubClass sc = new SubClass();
}
}
(四)基本堆栈模型
- 栈:不直接存放对象,而是存放对象的引用
- 堆:存放所有new出来的对象
- 常量池:存放字符串常量和基本类型常量(public static final类型)
class Cat{
int color,weight,height;
public Cat(int color, int weight, int height){
this.color = color;
this.weight = weight;
this.height = height;
}
}
public class TestEquals {
public static void main(String[] args){
Cat c1 = new Cat(1,1,1);
Cat c2 = new Cat(1,1,1);
System.out.println(c1 == c2);
System.out.println(c1.equals(c2));
}
}
运行结果均为false
- 了解基本的堆栈模型之后就知道,比较两个对象相同永远不能通过比较对象的引用是否相同来判断
- Object的Equals()方法默认比较的是两个对象的引用所指向的区域是否是同一区域,很多时候需要重写该方法来达到判断内容是否相同的目的