2018.8.25 晴朗的天气格外的热!!!
Java 序列化与反序列化(https://blog.youkuaiyun.com/wangloveall/article/details/7992448/)
1.Java序列化与反序列化是什么:
Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。
2.为什么需要Java序列化与反序列化
序列化的两种非常重要的应用:
使用序列化将对象集合保存到磁盘文件中,并按照它们被存储的样子获取它们。
通过网络将对象集合传送到另一台计算机上。
3.为什么只能用序列化和反序列化
在磁盘文件中,不能去保存和恢复对象的内存地址是因为对象被重载时,它可能占据的是与原来完全不同的内存地址。
在网络传输中,不同的处理器之间通信时,对象占据的内存地址也是完全不同。
4.序列化和反序列化的好处
序列化就是每个对象都是用一个序列号保存的,这就是这种机制被称为序列化的原因。
5.实现Java对象序列化与反序列化的方法
(1).JDK库中的序列化API实现二进制序列化
(2).XML
(3).JSON
(4).Protostaff
6.JDK库中序列化与反序列化:
(1)对象序列化包括如下步骤:
创建一个对象输出流,它可以包装一个其他类的目标输出流,如文件输出流;
通过对象输出流的writeObject()方法写对象。
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("empoyee.dat"));
Employee harry = new Employee("Harry Hacker", 5000, 1989, 10, 1);
Maneger boss = new Manager("Carl Cracker", 7000, 1984, 12, 15);
oos.writeObject(harry);
oos.writeObject(boss);
(2)对象反序列化包括如下步骤:
创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
通过对象输入流的readObject()方法以这些对象被写出的顺序读取对象并获得它们。
ObjectInputStream ois = new ObjectInputStream (new FileInputStream("empoyee.dat"));
Employee e1 = (Employee)ois.readObject();
Maneger e2 = (Manager)ois.readObject();
(3)对于那么需要序列化与反序列化的对象,对应的类必须要实现JDK库的相关API,有以下三种方法:
若Club类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化
ObjectOutputStream采用默认的序列化方式,对Club对象的非transient的实例变量进行序列化。
ObjcetInputStream采用默认的反序列化方式,对对Club对象的非transient的实例变量进行反序列化。
若Club类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。
ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。
若Club类实现了Externalnalizable接口,且Club类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。
ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。
和很多NoSQL数据库(例如Memcache、Ehcache)的客户端不同,Jedis本身没有提供序列化的工具,也就是说开发者需要自己引入序列化的工具。
(1).JDK库中的序列化API实现二进制序列化(序列化对象实现Serializable)
private static byte[] serialize(Object object) {
ObjectOutputStream objectOutputStream = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(object);
byte[] getByte = byteArrayOutputStream.toByteArray();
return getByte;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static Object unserizlize(byte[] binaryByte) {
ObjectInputStream objectInputStream = null;
ByteArrayInputStream byteArrayInputStream = null;
byteArrayInputStream = new ByteArrayInputStream(binaryByte);
try {
objectInputStream = new ObjectInputStream(byteArrayInputStream);
Object obj = objectInputStream.readObject();
return obj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
(2).XML
首先,必须要在要被序列化的对象的类上注释@XmlRootElement(name = "Club")
private static String serialize(Object object) {
StringWriter stringWriter = null;
try {
stringWriter = new StringWriter();
JAXBContext jContext = JAXBContext.newInstance(object.getClass());
Marshaller marshaller = jContext.createMarshaller();
marshaller.marshal(object, stringWriter);
} catch (JAXBException e) {
e.printStackTrace();
}
return stringWriter.toString();
}
private static Object unserizlize(Class<Club> clazz, String xmlString) {
Object xmlObject = null;
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader stringReader = new StringReader(xmlString);
xmlObject = unmarshaller.unmarshal(stringReader);
} catch (JAXBException e) {
e.printStackTrace();
}
return xmlObject;
}
(3)使用JSON实现序列化和反序列化
Java下常用的JSON工具类库主要有以下几种:
JSON-lib
FastJson
Jackson
Gson
以JSON-lib为例:
private static String serialize(Object object) {
JSONObject jsonObject = JSONObject.fromObject(object);
String getString = jsonObject.toString();
return getString;
}
private static Object unserizlize(String jsonString) {
new JSONObject();
JSONObject jObject = JSONObject.fromObject(jsonString);
JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "MM/dd/yyyy HH:mm:ss" }));
Object jsonObject = JSONObject.toBean(jObject, Club.class);
return jsonObject;
}
以FastJson为例:
Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。
(2)FastJson优点:
FastJson数度快,无论序列化和反序列化,都是目前Java中最快的。
功能强大(支持普通JDK类包括任意Java Bean Class、Collection、Map、Date或enum)。
零依赖(没有依赖其它任何类库)
(3)FastJson主要API
1. 将对象序列化成json字符串
String com.alibaba.fastjson.JSON.toJSONString(Object object)
2. 将json字符串反序列化成对象
<T> Project com.alibaba.fastjson.JSON.parseObject(String text, Class<T> clazz)
3. 将json字符串反序列化成JSON对象
JSONObject com.alibaba.fastjson.JSON.parseObject(String text)
4.根据key 得到json中的json数组
JSONArray com.alibaba.fastjson.JSONObject.getJSONArray(String key)
5. 根据下标拿到json数组的json对象
JSONObject com.alibaba.fastjson.JSONArray.getJSONObject(int index)
6.. 根据key拿到json的字符串值
String com.alibaba.fastjson.JSONObject.getString(String key)
7. 根据key拿到json的int值
int com.alibaba.fastjson.JSONObject.getIntValue(String key)
8. 根据key拿到json的boolean值
boolean com.alibaba.fastjson.JSONObject.getBooleanValue(String key)
实例:
private static String serialize(Object object) {
String getString = JSON.toJSONString(object);
return getString;
}
private static Object unserizlize(String jsonString) {
Object jsonObject = JSON.parseObject(jsonString, Club.class);
return jsonObject;
}
JSON与XML优缺点对比分析
(1)JSON的优点:
与XML相比,JSON更加的简洁,我们可以一眼就看出其中的内容,方便检查排错
JSON更加轻量级,不管是编写,传输,还是解析都更加高效
JSON在传输过程中采用了压缩技术,更加的节省宽带
众多的语言支持,如javascript,python,C,C++等主流语言都支持
因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。
(2)XML的优点:
格式统一,符合标准;
容易与其他系统进行远程交互,数据共享比较方便
(3)XML的缺点:
XML文件庞大,文件格式复杂,传输占带宽;
服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
服务器端和客户端解析XML花费较多的资源和时间。
(4)使用Protostuff实现序列化与反序列化
https://blog.youkuaiyun.com/ssjq123/article/details/82055319