Java序列化
# Java序列化
# Properties类
Class Properties
java.lang.Object java.util.Dictionary<K,V> java.util.Hashtable<Object,Object> java.util.Properties
实现接口
Serializable , Cloneable , Map < Object , Object >
// ".properties文件" 与 Properties 类
实现本地文件存储数据 Properties,每一个 Key(键)和 Value(值)都有对应的字符串储存在文件中
方法
返回 | 方法 | 说明 |
---|---|---|
String | getProperty(String key) | 获取指定的键 |
void | list(PrintStream out) | 打印到字节输出流 |
void | list(PrintWriter out) | 打印到字符输出流 |
void | load(InputStream inStream) | 从输入字节流读取键、值 |
void | load(Reader reader) | 从输入字符流读取键、值 |
void | loadFromXML(InputStream in) | 字节输入流中的XML文档表示的所有属性加载到此属性表中 |
void | store(OutputStream out, String comments) | 将 键、值 写入 Properties表中,写入格式是字节输出流 |
void | store(Writer writer, String comments) | 将 键、值 写入 Properties表中,写入格式是字输出符流 |
void | storeToXML(OutputStream os, String comment) | 发出Properties表中所有键、值的XML文档 |
void | storeToXML(OutputStream os, String comment, String encoding) | 指定编码发 出Properties表中所有键、值的XML文档 |
Set<String> | stringPropertyNames() | 返回列表中的一组键 |
# 序列化 与 反序列化
# 序列化
Class ObjectOutputStream
java.lang.Object java.io.OutputStream java.io.ObjectOutputStream
实现接口
Closeable , DataOutput , Flushable , ObjectOutput , ObjectStreamConstants , AutoCloseable
可以通过使用流的文件来实现对象的持久存储 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象(发个文件到另一台电脑实现对象)
注意:
- 实现重构的对象必须实现 Java.io.Serializable 接口
- 重构对象的属性也必须实现 Java.io.Serializable 接口
以上说明是实现重构对象的前提
构造方法
ObjectOutputStream() ObjectOutputStream(OutputStream out)
方法 (方法自行API)
# 反序列化
Class ObjectInputStream
java.lang.Object java.io.InputStream java.io.ObjectInputStream
实现接口
Closeable , DataInput , ObjectInput , ObjectStreamConstants , AutoCloseable
ObjectInputStream用于恢复先前序列化的对象 构造方法
ObjectInputStream() ObjectInputStream(InputStream in)
方法 (方法自行API)
# 序列化限制
指定对象部分属性序列化
实现方式:
- 对象属性用 transient 修饰符 限制属性序列化
- 对象属性用 static 修饰符 限制属性序列化
- 对象实现 writeObject()方法 和 readObject()方法 进行对指定属性进行实例化
注意: 方法3 ,writeObject()方法 和 readObject()方法 必须是 私有 无返回,否则无效
//模板
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//写
private void writeObject(ObjectOutputStream out) throws IOException
//读
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
代码实例
Main类 (写入操作)
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
MySerializableUtil su = new MySerializableUtil();
//数据处理 ,储存
People p = new People("柏竹" , 20 , null);
List<String> childrenName = new ArrayList<>();
childrenName.add("黑猫");
childrenName.add("大鲸");
childrenName.add("白兔");
HaveAll haveAll = new HaveAll(7654321 , "网球" , 3);
haveAll.setChildrenName(childrenName);
p.setHaveAll(haveAll);
System.out.println("原始数据 : "+ p);
//数据 序列化
String fileName = "Date.txt";
try {
MySerializableUtil.mySerializableUtil(p , fileName);
System.out.println("Serialization OK!");
} catch (Exception e) {
e.printStackTrace();
}
//读取
System.out.println("读数据 : ");
Object o = su.myDeserialize(fileName);
System.out.println(o);
}
}
/*
原始数据 : People{name='柏竹', age=20, haveAll=HaveAll{money=7654321, house='网球', childrenNum=3}}
调用 writeObject() 限制!!!
Serialization OK!
读数据 :
调用 readObject() !!!
People{name='柏竹', age=20, haveAll=HaveAll{money=0, house='网球', childrenNum=3}}
*/
Input类 (读文件数据)(用于在别的地方读取对象)
public class Input {
public static void main(String[] args) {
MySerializableUtil su = new MySerializableUtil();
Object o = su.myDeserialize("Date.txt");
System.out.println(o);
}
}
MySerializableUtil类 (操作工具)
import java.io.*;
/**
* 序列化 与 序列化 工具类
*/
public class MySerializableUtil {
/**
* 序列化
* @param data 数据
* @param fileName 字节输出流
*/
public static void mySerializableUtil(Object data , String fileName){
try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
oos.writeObject(data);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 反序列化
* @param fileName 字节输入流
* @return 返回获取的对象
*/
public static Object myDeserialize(String fileName){
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
return ois.readObject();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
People类 (存储对象)
import java.io.IOException;
import java.io.Serializable;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* 实现Serializable接口
*/
public class People implements Serializable {
String name;
//年龄不能序列化
static int age;
/**人的明细*/
HaveAll haveAll;
//指定对象序列化
private void writeObject(ObjectOutputStream out) throws IOException {
System.out.println(" 调用 writeObject() 限制!!!");
out.writeObject(name);
out.writeObject(haveAll);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
System.out.println(" 调用 readObject() !!!");
name =(String) in.readObject();
haveAll = (HaveAll) in.readObject();
}
public People() {
}
public People(String name , int age , HaveAll haveAll) {
this.name = name;
this.age = age;
this.haveAll = haveAll;
}
public void setHaveAll(HaveAll haveAll) {
this.haveAll = haveAll;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public HaveAll getHaveAll() {
return haveAll;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", haveAll=" + haveAll +
'}';
}
}
HaveAll类 (存储PeoPle对象中的对象)
import java.io.Serializable;
import java.util.List;
public class HaveAll implements Serializable {
// 余额 & 爱好 & 已有的孩子 & 孩子名字集合
// 余额不能序列化对象
private transient long money;
String house;
int childrenNum;
List<String> childrenName;
//不多写了
public HaveAll() { }
public HaveAll(long money , String house ,int childrenNum) {
this.money = money;
this.house = house;
this.childrenNum = childrenNum;
}
public List<String> getChildrenName() {
return childrenName;
}
public void setChildrenName(List<String> childrenName) {
this.childrenName = childrenName;
}
public void setMoney(long money) {
this.money = money;
}
public void setHouse(String house) {
this.house = house;
}
public void setChildrenNum(int childrenNum) {
this.childrenNum = childrenNum;
}
public long getMoney() {
return money;
}
public String getHouse() {
return house;
}
public int getChildrenNum() {
return childrenNum;
}
@Override
public String toString() {
return "HaveAll{" +
"money=" + money +
", house='" + house + '\'' +
", childrenNum=" + childrenNum +
'}';
}
}
# Externalizable接口 序列化
继承接口 Serializable
实现类 ActivationDataFlavor , DataFlavor , MimeType , MLet , PrivateMLet
Externalizable接口 也能实现 序列化 和 反序列化 ,因继承 Serializable接口。
使用该接口需要定义 writeExteranl()
、 readExternal()
抽象方法才可以实现序列化与反序列化
//模板
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//写
public void writeExternal(ObjectOutputStream out) throws IOException
//读
public void readExternal(ObjectInputStream in) throws IOException, ClassNotFoundException
实现方式: 在以上代码中的 People类 更改
import java.io.IOException;
import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* 实现Serializable接口
*/
public class People implements Externalizable {
String name;
//年龄不能序列化
static int age;
/**人的明细*/
HaveAll haveAll;
//指定对象序列化
public void writeExternal(ObjectOutputStream out) throws IOException {
System.out.println(" 调用 writeObject() 限制!!!");
out.writeObject(name);
out.writeObject(haveAll);
}
public void readExternal(ObjectInputStream in) throws IOException, ClassNotFoundException{
System.out.println(" 调用 readObject() !!!");
name =(String) in.readObject();
haveAll = (HaveAll) in.readObject();
}
//·····省略
}