首页 > 编程知识 正文

java中的序列化与反序列化,java序列化和反序列化理解

时间:2023-05-06 07:40:57 阅读:229173 作者:4674

对象序列化(serialization)和反序列化(deserialization)是将对象转化为便于传输的格式进行发送和接收的两个操作。

哪些东西可以是字节?图片可以是字节,文件可以是字节,一个字符串也可以是字节,嗯,宇宙间的一切事物都可以用字节表示。当然,对象也可以是字节。java的序列化就是将对象转化为字节流,以便在进程或网络之间进行传输,而在接收方,需要以相同的方式对字节流进行反序列化,得到传输的对象。

1,实现Serializable接口

package com.java; import java.io.Serializable;import java.util.ArrayList;import java.util.List; public class Player implements Serializable{ public Player(long playerId, int age, String name) {this.playerId = playerId;this.age = age;this.name = name;}private long playerId;private int age;private String name;private List<Integer> skills = new ArrayList<>(); get() /set()方法}

2.对象序列化,Java中通过对象流 ObjectOutputStream 进行序列化。

public static byte[] serializable(Object out) throws Exception {//用于序列化后存储对象ByteArrayOutputStream byteArrayOutputStream = null;//java序列化APIObjectOutputStream objectOutputStream = null;try {byteArrayOutputStream = new ByteArrayOutputStream();objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);//将out对象进行序列化objectOutputStream.writeObject(out);//测试验证输入(获取字节数组)byte[] bs = byteArrayOutputStream.toByteArray();//将数组转化为字符串输入System.out.println(Arrays.toString(bs));return bs;} catch (IOException e) {e.printStackTrace();}finally {//关闭最外层的流(内部流会自动关闭)objectOutputStream.close();}return null;}

3.反序列化为对象,Java中通过对象流 ObjectInputStream 进行序列化。

public static player deserializable(byte[] bs) throws Exception {//创建存放二进制数据的APIByteArrayInputStream byteArrayInputStream = null;//创建反序列化对象ObjectInputStream objectInputStream = null;try {byteArrayInputStream = new ByteArrayInputStream(bs);objectInputStream = new ObjectInputStream(byteArrayInputStream);//校验测试Player player = (Player) objectInputStream.readObject();System.out.println(player.toString());} catch (IOException e) { player = null;e.printStackTrace();}finally {objectInputStream.close();} return player;}

本以为这样就可以了,但使用过程中会有一些问题出现,总结一些遇到的问题吧

测试:

public class TempTest { public static void main(String[] args) { CarData date= new CarData(); Object value = new Object("a","123"); system.out.println(Arrays.toString(serializable(value))); system.out.println(deserialzable(data.getString().getBytes()));}

4.遇到的问题及解决方式;

(1)打印字符串乱码

其中String和byte[]转换:

String string = "hello world"; //Convert to byte[] byte[] bytes = string.getBytes(); //Convert back to String String s = new String(bytes);

输入一些数据测试,出现乱码打印结果:

�� sr java.util.ArrayListx����a� I sizexp w sr com.alibaba.fastjson.JSONObject L mapt Ljava/util/Map;xpsr java.util.HashMap���`� F loadFactorI thresholdxp?@ t at 123xx

解决方法:

原因:string利用 byte[] bytes = string.getBytes(); String s = new String(bytes);方法和bute[]互转时会出现丢失两字节识别码,所以发生乱码// 使用Base64解码 System.out.println(deserializable(Base64.getDecoder().decode(value.getstring())));//value 是一个自定义复杂类型数据,通过getstring()内部方法得到string类型数据 打印结果:rO0ABXNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAABdwQAAAABc3IAH2NvbS5hbGliYWJhLmZhc3Rqc29uLkpTT05PYmplY3QAAAAAAAAAAQIAAUwAA21hcHQAD0xqYXZhL3V0aWwvTWFwO3hwc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAADHcIAAAAEAAAAAF0AAFhdAADMTIzeHg=[{"a":"123"}]

(2)java.util.Base64报“java.lang.IllegalArgumentException: Illegal base64 character d”的问题

原因:Base64是一种字符串编码格式,采用了A-Z,a-z,0-9,“+”和“/”这64个字符来编码原始字符(还有垫字符“=”)。一个字符本身是一个字节,也就是8位,而base64编码后的一个字符只能表示6位的信息。也就是原始字符串中的3字节的信息编码会变成4字节的信息。Base64的主要作用是满足MIME的传输需求。 在Java8中Base64编码已经成为Java类库的标准,且内置了Base64编码的编码器和解码器。Base64.getDecoder().decode() 修改为 Base64.getMimeDecoder().decode()

(3)java.io.EOFException报空异常

deSerializable()方法中的将构造ObjectInputStream 对象,放在捕获异常try{}catch{}外面

(4)反序列化过程引发了 java.io.EOFException异常

原因:可能是实现Serializable接口的时候重新实现了tostring()方法,这个格式写的不对,导致异常,最简单的方法就是用Serializable自己的toString()方法.

 

以上,仅供个人学习记录.

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。