java字节序、主机字节序和网络字节序扫盲贴

来源:互联网 发布:邹平php 编辑:程序博客网 时间:2024/05/16 12:53

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

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

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

\

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

至于计算机到底是BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有关的,一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN。IA架构(Intel、AMD)的CPU中是Little-Endian,而PowerPC 、SPARC和MotZ喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcm9sYbSmwO3G98rHQmlnLUVuZGlhbqGj1eLG5Mq1vs3Kx8v5zr21xNb3u/rX1r3a0PKho7b4zfjC59fWvdrQ8srH1rjK/b7d1NrN+MLnyc+0q8rkyrHKx7Tzzbe7ucrH0KHNt7XEo6zU2kludGVybmV0tcTN+MLn19a92tDyysdCSUctRU5ESUFOoaPL+c69tcRKQVZB19a92tDy1ri1xMrH1NpKQVZB0OnE4rv61tC24NfWvdrA4NDNyv2+3bXEtOa3xcuz0PKjrEpBVkHX1r3a0PLSssrHQklHLUVORElBTqGjv8m8+834wue6zUpWTba8ssnTw7XEyse089fWvdrQ8qOsuPbIy7jQvvW+zcrH0vLOqtXi1tbX1r3a0PKxyL3Pt/u6z8jLwOC1xM+wud+ho9PJ09pKVk274bj5vt2117LjtcSy2df3z7XNs7rNQ1BV19S2r7340NDX1r3a0PK1xNequ7ujrMv50tTO0sPHyrnTw2phdmG9+NDQzfjC57Hgs8yjrLy4uvW40L71sru1vdfWvdrQ8rXEtObU2qGjPC9wPgo8cD4gICAgICDEx8O0amF2YcDvw+ajrNT1w7TF0LbPxOO1xLzGy+O7+srHtPO2y7TmtKKhoru5ysfQobbLtOa0osTYo79KREvOqs7Sw8fM4bmp0ru49sDgQnl0ZU9yZGVyo6zNqLn90tTPwrT6wuu+zb/J0tTWqrXAu/rG97XE19a92tDyPC9wPgo8cD48L3A+CjxwcmUgY2xhc3M9"brush:java;">System.out.println(ByteOrder.nativeOrder());在java.nio包下提供了ByteOrder、ByteBuffer等于字节序相关的类,我们也可以改变JVM中默认的字节序。该例子来源于

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

代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
packagenet.aty.util;
 
 
importjava.nio.ByteBuffer;
importjava.nio.ByteOrder;
importjava.util.Arrays;
 
publicclass JVMEndianTest {
     
    publicstatic void main(String[] args) {
         
        intx = 0x01020304;
         
        ByteBuffer bb = ByteBuffer.wrap(newbyte[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]

http://www.2cto.com/kf/201404/291765.html


0 0
原创粉丝点击