日常使用中, 存在一些场景需要把java对象转为字节数组。 或者字节数组转java对象。 一般来说有以下几种场景。

我们来分别讨论。

1. JAVA之间相互通讯场景

这种场景常见于java应用之间的通讯, 比如A应用向B应用获取数据。 或者读取B应用预先存的数据。

此时一般来说实体类实现java自带的序列化接口, 然后使用以下方式即可完成序列化。

    private Object byteToObject( byte[] bytes) {java.lang.Object obj;try {//bytearray to objectByteArrayInputStream bi = new ByteArrayInputStream(bytes);ObjectInputStream oi = new ObjectInputStream(bi);obj = oi.readObject();bi.close();oi.close();}catch(Exception ae) {throw ae;}return obj;}public byte[] objectToByte(Object obj){byte[] bytes;try {ByteArrayOutputStream bo = new ByteArrayOutputStream();ObjectOutputStream oo = new ObjectOutputStream(bo);oo.writeObject(obj);bytes = bo.toByteArray();bo.close();oo.close();    }catch(Exception ae) {throw ae;}return(bytes);}

此种方式适合java语言之间的通讯或者数据交互。不适合跨语言。而且也不适合于IM场景。

2. 仅仅做数据储存方案

储存方案一般来说要区分是否跨语言, 数据储存体积, 读取效率等问题。 这种建议优先采用文本化协议比较好(比如json, xml等), 方便开发者校验和开发。 如果使用二进制储存, 虽然体积小了。但是不方便开发和核对。出了bug不方便排查。

3. 跨语言通讯场景

跨语言通讯场景一般是最多的, 比如物联网。 IM通讯, 视频等等。由于业务的特殊性,所以一般会采用二进制协议。而且是私有协议居多。在进行序列化时候。java自带的序列化机制并不能很好的满足我们的需求。这个时候就需要用户自己手动进行序列化过程。

主要使用到 java的 ByteBuffer.

    public class Student {byte height;int age;long phone;}public static void main(String[] args) {Student student = new Student();student.height = (byte) 185;student.age = 23;student.phone = 18380330237L;// 对象序列化到字节数组ByteBuffer byteBuffer = ByteBuffer.allocate(100).order(ByteOrder.BIG_ENDIAN);byteBuffer.put(student.height);byteBuffer.putInt(student.age);byteBuffer.putLong(student.phone);byte[] array = byteBuffer.array();// 字节数组序列化到对象byteBuffer = ByteBuffer.allocate(100).order(ByteOrder.BIG_ENDIAN);byteBuffer.put(array);byteBuffer.position(0);Student student2 = new Student();student2.height = byteBuffer.get();student2.age = byteBuffer.getInt();student2.phone = byteBuffer.getLong();}

上面的代码中, 列举出了我们平时序列化的方式。虽然使用字节数组可以高效率的完成对象的封装和转换。 但是需要注意以下问题:

  • 字节数组大小端双方一定要一致
  • 如果存在list, array 等属性, 要注意OOM
  • buffer使用时如果时directbuffer, 需要注意OOM
  • 注意序列化时空指针和默认值的处理
  • 序列化数组不全时,注意数据对齐进行填补
  • 处理 字符串时,注意字符编码集

其实跨语言通讯和私有协议这种场景,大都是大厂最先遇到并提出解决方案的。比如google 的 javastruct(2004年就出来了); 或者 magic-byte;

如果使用框架,以上的代码可以如下写了(注意类的定义和上面有所不同):

@MagicClass(byteOrder = ByteOrder.BIG_ENDIAN)public class Student {@MagicField(order = 1)byte height;@MagicField(order = 2)int age;@MagicField(order = 3)long phone;// gettter setter}public static void main(String[] args) {Student student = new Student();student.height = (byte) 185;student.age = 23;student.phone = 18380330237L;// 对象序列化到字节数组byte[] array = MagicByte.unpackToByte(student);// 字节数组序列化到对象Student student2 = MagicByte.pack(array, Student.class);}

在定义类时, 即把序列化方式定义完成。然后只需要调用函数即可进行序列化和反序列化了。

怎么样, 这样是不是简单多了。

附上开源项目的地址:

GitHub - MisterChangRay/magic-byte: faster convert byte to java object toolhttps://github.com/MisterChangRay/magic-byte

以上就是总结的一些java 对象转字节的方式。 大家按需索取吧。

JAVA对象转字节数组相关推荐

  1. java字符串的字节数组_Java字节数组到字符串到字节数组

    我正在尝试将byte []转换为字符串,将byte []的字符串表示形式转换为byte []的转换...我将byte []转换为要发送的字符串,然后我期望我的Web服务(用python编写)将数据直接 ...

  2. java 字节数组作用_这段java代码中字节数组b起到了什么作用?

    importjava.io.*;importjavax.swing.*;publicclassIOMonitor{publicstaticvoidmain(String[]temp){//TODO自动 ...

  3. java对象与byte[]数组之间的相互转化,压缩解压缩操作

    下面介绍一下java对象之间和byte[]数组之间的相互转化.并对byte[]数据进行压缩操作.java对象转化为byte[]数组可用于redis中实现缓存.(这里暂不做介绍).话不多说直接开实例: ...

  4. Java语言对字节数组截取指定长度

    Java通过 arraycopy来实现字节数组截取,类比于C语言memcpy,代码如下: System.arraycopy(src, srcPos, dest, destPos, length);参数 ...

  5. java字符串转换成字节数组_将Java字符串转换为字节数组

    我有一个要加密的字节数组,然后转换为字符串,以便可以传输. 当我收到字符串时,我必须将字符串转换回字节数组,以便可以对其进行解密. 我检查了接收到的字符串是否与发送的字符串(包括长度)匹配,但是当我使 ...

  6. JAVA——实现把字节数组转成字符串

    * String类 * 构造方法public String(byte[] bytes) : 把字节数组转成字符串 代码如下: public class FileInputStreamDemo3 {pu ...

  7. bytearray java_详解Java中ByteArray字节数组的输入输出流的用法

    ByteArrayInputStream 介绍ByteArrayInputStream 是字节数组输入流.它继承于InputStream. 它包含一个内部缓冲区,该缓冲区包含从流中读取的字节:通俗点说 ...

  8. java 如何操作字节数组_实例解析Java字节数组操作模式代码

    字节数组的关键是它为存储在这部分内存中的每个8位值提供索引(快速)和精确的原始访问,并且您可以操纵这些字节来控制每个位.缺点是计算机只将每个条目视为一个独立的8位数字--这可能是您的程序正在处理的,或 ...

  9. Java:GB18030字节数组与UTF8互转

    2019独角兽企业重金招聘Python工程师标准>>> JDK:1.8 当我们需要把一个以GB18030编码的字节数组转换为UTF8字符串,我们可以使用nio中的编解码. 1.GB1 ...

最新文章

  1. Camel之AsyncProcessor
  2. Zend Studio出现 Some characters cannot be mapped using GBK character encoding 错误
  3. 制作linux安装镜像文件,制作CentOS 6.5一键自安装ISO镜像光盘 | 聂扬帆博客
  4. [原创]换一份工作要考虑什么?
  5. t3 修改服务器配置,t3如何修改服务器地址
  6. 如何在 C# 中使用隐式和显式操作符
  7. 整理Linux查看系统日志的一些经常使用命令
  8. python旋转数组_Python3实现旋转数组的3种算法
  9. BZOJ 1646: [Usaco2007 Open]Catch That Cow
  10. 使用stanford nlp进行依存句法分析
  11. 面向对象——类设计(一)
  12. python狗屁不通文章生成器_狗屁不通文章生成器,哈哈哈
  13. 鼠标不受控制一直向右移动的解决办法
  14. php tp框架面试问题,Thinkphp面试问题及答案
  15. 浙江大学-研究生机器学习课程-课堂笔记
  16. 矢量网络分析仪的基本原理
  17. 大会没看够?2021 Google 开发者大会总结看这里!
  18. 锋迷商城spring-vue项目流程和笔记
  19. 下列内容属于计算机房控制功能的是,前厅服务员中级理论知识试卷及答案2
  20. AlarmManager 中 setRepeating用法

热门文章

  1. 雷军:中国的乔布斯?!--没人看我来转,疑似水文,太晚了,稍侯拍砖
  2. 你认为程序员的最高境界是什么?
  3. 爬虫框架 Scrapy 教程详解
  4. cpu使用率 htop显示_最全最强的htop使用详解
  5. EXCEL列序号的加法
  6. 倍思畅享系列Type-C转USB3.0 RJ45网口HUB转换器 极简设计非凡功能
  7. C语言双感叹号作用!!
  8. php调用父类构造,php调用父类构造方法是什么
  9. 星型结构 和 雪花型结构区别
  10. 小故事大人生 -----七个顶级心理寓言