java 为什么用大端_Java中的大端和小端
Java整型的字节序是()
A.Little-Endian(小端)
B.Big-Endian(大端)
C.由运行程序的CPU决定
D.由编译程序的CPU决定
对于大小端,我估计肯定有很多开发人员跟我一样都没听过
由于Java是跨平台的,JVM为我们屏蔽了大量的底层细节和复杂性,导致在平时的时候根本不会接触到。以下是我通过大量咨询,查找整理的结果。
字节序:指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序,有大端和小端两种方式
大端:指高位字节存放在内存的低地址端,低位字节存放在内存的高地址端。十六进制整数0x01020304在内存中存储方式,由于一个整型在内存中占4个字节,因此被划分成4份分别存储在连续的内存地址位中
小端:指低位字节放在内存的低地址端,高位字节放在内存的高地址端。同样0x01020304在内存中的存储方式为
在计算机中既可以是大端存储,也可以小端存储,跟CPU架构有关,IA架构(Intel、AMD)的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola处理器是Big-Endian
基于Java8,在Java中提供了一个api可以获取CPU使用的字节序:
ByteOrder byteOrder = ByteOrder.nativeOrder();
//LITTLE_ENDIAN,CPU是Intel的
System.out.println(byteOrder);
通过查看ByteOrder.nativeOrder() 源码,其最后调用了Bits.byteOrder()
// -- Processor and memory-system properties --
private static final ByteOrder byteOrder;
static ByteOrder byteOrder() {
if (byteOrder == null)
throw new Error("Unknown byte order");
return byteOrder;
}
/**
* 通过返回0x01,还是0x08来判断CPU使用的是BIG_ENDIAN,还是LITTLE_ENDIAN
**/
static {
long a = unsafe.allocateMemory(8);
try {
unsafe.putLong(a, 0x0102030405060708L);
byte b = unsafe.getByte(a);
switch (b) {
case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break;
case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break;
default:
assert false;
byteOrder = null;
}
} finally {
unsafe.freeMemory(a);
}
}
对于Java,其实既有使用大端,也有使用小端,对于ByteBuffer,默认使用的Big-Endian(大端),也可以对默认方式进行修改,如下例子
int x = 0x01020304;
ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[4]);
byteBuffer.asIntBuffer().put(x);
String before = Arrays.toString(byteBuffer.array());
System.out.println("默认字节序:"+byteBuffer.order().toString() + "," + "内存数据:"+before);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
byteBuffer.asIntBuffer().put(x);
String after = Arrays.toString(byteBuffer.array());
System.out.println("修改字节序:"+byteBuffer.order().toString()+","+"内存数据:"+after);
默认字节序:BIG_ENDIAN,内存数据:[1, 2, 3, 4]
修改字节序:LITTLE_ENDIAN,内存数据:[4, 3, 2, 1]
通过查看ByteBuffer.wrap,其声明了一个HeapByteBuffer
public static ByteBuffer wrap(byte[] array, int offset, int length)
{
try {
return new HeapByteBuffer(array, offset, length);
} catch (IllegalArgumentException x) {
throw new IndexOutOfBoundsException();
}
}
所以byteBuffer.asIntBuffer()实际调用了HeapByteBuffer中的方法
public IntBuffer asIntBuffer() {
int size = this.remaining() >> 2;
int off = offset + position();
return (bigEndian
? (IntBuffer)(new ByteBufferAsIntBufferB(this,-1,0,size,size,off))
: (IntBuffer)(new ByteBufferAsIntBufferL(this,-1,0,size,size,off)));
}
bigEndian表示是否是大端,默认为true,所以后面put的时候实际是往ByteBufferAsIntBufferB大端中存储数据,但也可以调整为使用小端来存储数据,byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
这题的答案是B,但实际却是Java中既能有大端也能有小端,只是Java默认使用了大端
java 为什么用大端_Java中的大端和小端相关推荐
- 数据格式:大端模式(Big-endian)和小端模式(Little-endian)
有没有想过当定义一个变量的时候,这个变量在内存中是如何存放的呢?这就涉及到数据格式中的大端模式(Big-endian)和小端模式(Little-endian) 大端模式(Big-endian):高位字 ...
- java可以多重继承吗_Java中的多重继承与组合vs继承
java可以多重继承吗 有时我写了几篇有关Java继承,接口和组成的文章. 在这篇文章中,我们将研究多重继承,然后了解组成优于继承的好处. Java中的多重继承 多重继承是创建具有多个超类的单个类的能 ...
- java中有没有栈_Java中堆和栈有什么区别
stack 和 heep 都是内存的一部分stack 空间小,速度比较快, 用来放对象的引用heep 大,一般所有创建的对象都放在这里.栈(stack):是一个先进后出的数据结构,通常用于保存方法(函 ...
- java 基本类型 引用_java中 引用类型 和 基本类型 有何区别?
栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newa ...
- java构造器详解_Java中关于构造器的使用详解
这篇文章主要介绍了Java构造器使用方法及注意事项的相关资料,这里举例说明如何使用构造器及需要注意的地方,需要的朋友可以参考下 Java构造器使用方法及注意事项 超类的构造器在子类的构造器运行之前运行 ...
- java string对象名称_java中常见对象——String
字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. A:字符串字面值"abc"也可以看成是一个字符串对象. B:字符串是常量,一旦被赋值,就不能被改变. 构造方法: ...
- java读取文件 路径_Java中的获取文件的物理绝对路径,和读取文件
获取文件的绝对路径,读取该文件 一.文件目录打印图 下面的文件目录图,是项目中文件的位置信息:下面的例子是按照这个图来演示的. . |-- java | |-- ibard | | |-- demo1 ...
- java多线程 线程安全_Java中的线程安全
java多线程 线程安全 Thread Safety in Java is a very important topic. Java provides multi-threaded environme ...
- java 异常处理发生异常_Java中的异常处理
java 异常处理发生异常 Exception Handling in Java is a very interesting topic. Exception is an error event th ...
最新文章
- vscode提交代码
- win7环境变量设置
- 数据库:分布式事务的解决方案
- 【干货】你如何寻找APP?发现优秀 APP 的一些途径
- oralce group by字符串拼接
- mount: 未知的文件系统类型“vboxsf”_第六章--文件系统管理
- python中集合用法大全_python中集合的用法
- python网课哪个好-python网课学习笔记--4
- ora-01031:insufficient privileges解决方法总结
- Pod install 慢, pod update 慢, Cocoapods setup下载缓慢,手动解决方案
- OpencV使用fitEllipse拟合椭圆后,获取椭圆参数
- 全网最全的 Java 各类技术栈架构图汇总(建议收藏)
- 【数字IC】深入浅出理解I2C协议
- Linux 文件系统
- 第三方微信授权登录的iOS代码分析
- G1 GC详解及设置
- linux网络设备和一些知识点总结
- [mysql]存储过程/存储函数
- 自动领取起点网页版的经验值
- 西邮Linux兴趣小组2019-2021年纳新面试题解析
热门文章
- 流言终结:JS字符搜索的飞雷神之术?
- python开源报表系统详细操作流程_手把手教你实现自动化报表系统
- Ubuntu 16.04 用户登陆界面 循环输入密码 进不去图形界面
- tabe-cell实现两栏等高效果
- ES6模块加载方案 CommonJS和AMD ES6和CommonJS
- Javascript Hoisting
- limit分页查询的学习
- ffmpeg之音频转码及重采样
- 七牛云 转码_七牛云的音频转码,微信的speex音频转码为mp3格式
- 倒频谱分析 matlab,倒频谱分析
- MATLAB Simulink
- MathWorks 中国