第二章 缓冲区(12)

2.4.1字节顺序

非字节类型的基本类型,除了boolean都是由多个字节组成的。这些基本类型和它们的大小总结在下面的表2.1中。

Boolean类型表示两个值:truefalse。一个byte能表示256个唯一的数值,因而boolean类型不能准确的对应到一个或多个字节上。所有的buffer都是由byte构建起来的。NIO的构架决定了实现boolean类型的buffer会存在问题,总之boolean类型的buffer是值得商榷的。

2.1 基本数据类型及其大小

数据类型

大小(byte

Byte

1

Char

2

Short

2

Int

4

Long

8

Float

4

Double

8

每个基本类型都是以连续字节的形式存储在内存空间中。例如,32位值为0x037fb4c7(十进制为:58700999)的Int类型可能像图2.14一样字节顺序保存在内存中。你应该注意到前面句子里的“可能”这个词了。尽管字节大小已经得到了统一,但是字节顺序一直没有统一。上面int类型的值也可以保存为图2.15所示的字节顺序。

2.14 大端字节顺序

2.15 小端字节顺序

通常多字节数值存储在内存中的形式被认为是有端的。如果数值的高位保存在系统的低位地址空间,那么系统就是大端系统(如图2.14所示)。如果数值的低位保存在系统的地位地址空间,那么系统就是小端系统(如图2.15所示)。

字节顺序的大小端是跟软件设计者无关的,它通常取决于硬件设计。字节的两种端,现在被广泛应用。两种端都具有相应的优点。Intel处理器使用小端字节顺序。MotoloraCPU家族、SUNSparcPowerPC CPU架构都采用大端字节顺序。

字节的大小端甚至超越了硬件设计。当Internet的设计者为了连接各种各样的计算机在设计IP系列协议时,他们意识到各种系统中在交换不同数值数据时因不同字节顺序带来的问题。因此IP协议定义了数值的字节顺序为大端。所有使用在IP包中的多字节数值,必须先从本地主机字节顺序转换为网络字节顺序。

java.nio包中,字节顺序被封装在ByteOrder类中。

package java.nio;

public final class ByteOrder{

public static final ByteOrder BIG_ENDIAN;

public static final ByteOrder LITTLE_ENDIAN;

public static ByteOrder nativeOrder();

public String toString();

}

ByteOrder类定义了两个常量,这些常量表示的是系统提取或者存储多字节数据到buffer中的字节顺序。这个类就像一个类型安全的枚举类型。它在public域中定义了两个ByteOrder对象实例。在JVM中只有两种ByteOrder的实例,因此ByteOrder可以使用==操作符进行比较。如果你想知道JVM运行的计算机硬件平台使用的字节顺序,你可以调用类的静态nativeOrder方法。它将返回两个常量中的一个。调用toString方法将返回BIG_ENDIAN或者是LITTLE_ENDIAN字符串。

每个buffer类都具有特定的字节顺序,可以通过调用order方法来查询。

public abstract class CharBuffer extends Buffer

Implements Comparable,CharSequence{

public final ByteOrder order();

}

这个方法返回ByteOrder中两个常量之一。对于除了ByteOrder之外的其他buffer类,字节顺序是一个只读的属性,可能因为buffer不同的创建方式而不同。除了ByteBuffer,其他通过allocate或者wrap方法创建的buffer类调用order方法将得到跟ByteOrder类调用nativeOrder方法同样的结果。因为存储在buffer中的数据在JVM中将作为基本数据类型直接读取。

ByteBuffer类跟其他Buffer类不同的是:不管系统本身的字节顺序,ByteBuffer缺省下总是使用大端字节顺序,这样做的好处是可以使字节码文件(.class)和序列化对象可以在任意的JVM正常工作。如果系统的默认字节顺序为小端的,那么这样可能影响性能。当把ByteBuffer中的数据当做其他基本类型访问时,使用本地字节顺序会提供性能。

当然,你可能对ByteBuffer类为什么需要字节顺序感到迷惑。但是如果你看看2.4.4小节,你会发现ByteBuffer对象提供了大量的方便存取其他基本类型数据的方法。这些方法对字节的转换就是依赖的ByteBuffer中的当前字节顺序。

ByteBuffer对象中的字节顺序可以通过调用传递ByteOrder.BIG_ENDIAN或者ByteOrder.LITTL_ENDIAN参数来改变。

Public abstract class ByteBuffer extends Buffer

Implements Comparable{

Public final ByteOrder order();

Public final order(ByteOrder bo);

}

如果一个buffer对象作为另一个对象的视图来创建(见2.4.3小节),那么调用这个bufferorder方法将返回的是原始buffer的字节顺序。这个视图buffer对象创建之后,它就不能改变字节顺序,如果原始的buffer对象在这个视图buffer创建之后改变,也不会影响到视图buffer的字节顺序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值