java 网络字节序_【数据结构】- Java字节序、主机字节序和网络字节序扫盲贴

Java程序员是幸福,因为相对于C/C++的不跨平台,JVM为我们屏蔽了大量的底层细节和复杂性,让我们能够将精力放在实现特定的业务逻辑上,所以使用java开发项目效率是比较高的。同时java程序员是悲哀的,就是因为JVM屏蔽了很多技术细节,导致java程序员基本功普遍较差,对一些基本概念理解不深,甚至根本没有听说过。作为一个java程序员,我深深的感到自己知识面的狭窄。无意中看到了字节序,以前竟然都不知道,这里记录下,扫个盲。

使用C/C++进行网络编程的程序员,肯定会接触到“字节序”的概念,但是使用java进行网络编程,却根本不会接触到“字节序”。为什么会这样呢?我们先从字节序说起。字节顺序是指占用内存多于一个字节类型的数据在内存中的存放顺序,有小端、大端两种顺序。小端字节序(little endian):低字节数据存放在内存低地址处,高字节数据存放在内存高地址处;大端字节序(bigendian):高字节数据存放在低地址处,低字节数据存放在高地址处。

Java中一个int型数据占用4个字节,假如有一个16进制的int数,int value = 0x01020304;采用不同的字节序,在内存中的存储情况见下图:

8b574d742636431cba83c072d02361b7.png

显然大字节序,是比较符合人类思维习惯的。

至于计算机到底是BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有关的,一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN。IA架构(Intel、AMD)的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola处理器是Big-Endian。这其实就是所谓的主机字节序。而网络字节序是指数据在网络上传输时是大头还是小头的,在Internet的网络字节序是BIG-ENDIAN。所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。可见网络和JVM都采用的是大字节序,个人感觉就是因为这种字节序比较符合人类的习惯。由于JVM会根据底层的操作系统和CPU自动进行字节序的转换,所以我们使用java进行网络编程,几乎感觉不到字节序的存在。

那么java里面,怎么判断你的计算机是大端存储、还是小端存储呢?JDK为我们提供一个类ByteOrder,通过以下代码就可以知道机器的字节序

System.out.println(ByteOrder.nativeOrder());

在java.nio包下提供了ByteOrder、ByteBuffer等于字节序相关的类,我们也可以改变JVM中默认的字节序。该例子来源于

http://blog.csdn.net/veryitman/article/details/6819017

代码如下:

packagenet.aty.util;importjava.nio.ByteBuffer;importjava.nio.ByteOrder;importjava.util.Arrays;public classJVMEndianTest {public static voidmain(String[] args) {int x = 0x01020304;

ByteBuffer bb= ByteBuffer.wrap(new byte[4]);

bb.asIntBuffer().put(x);

String ss_before=Arrays.toString(bb.array());

System.out.println("默认字节序 " + bb.order().toString() + "," + " 内存数据 " +ss_before);

bb.order(ByteOrder.LITTLE_ENDIAN);

bb.asIntBuffer().put(x);

String ss_after=Arrays.toString(bb.array());

System.out.println("修改字节序 " + bb.order().toString() + "," + " 内存数据 " +ss_after);

}

}

执行结果如下:

默认字节序 BIG_ENDIAN, 内存数据 [1, 2, 3, 4]

修改字节序 LITTLE_ENDIAN, 内存数据 [4, 3, 2, 1]

附工具类

classToBytesUtils {public static byte[] intToBytes(intvalue) {byte[] result = new byte[4];

result[0] = (byte)((value >> 24) & 0xFF);

result[1] = (byte)((value >> 16) & 0xFF);

result[2] = (byte)((value >> 8) & 0xFF);

result[3] = (byte)(value & 0xFF);returnresult;

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值