java ByteBuffer getInt() 问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6943858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ByteBuffer getInt() question
提问by 5YrsLaterDBA
We are using Java ByteBuffer for socket communication with a C++ server. We know Java is Big-endian and Socket communication is also Big-endian. So whenever the byte stream received and put into a ByteBuffer by Java, we call getInt() to get the value. No problem, no conversion.
我们使用 Java ByteBuffer 与 C++ 服务器进行套接字通信。我们知道 Java 是 Big-endian,而 Socket 通信也是 Big-endian。所以每当字节流被 Java 接收并放入 ByteBuffer 时,我们调用 getInt() 来获取值。没问题,没有转换。
But if somehow we specifically set the ByteBuffer byte order to Little-endian (my co-worker actually did this),
但是,如果我们以某种方式将 ByteBuffer 字节顺序专门设置为 Little-endian(我的同事实际上是这样做的),
will the Java automatically convert the Big-endian into the Little-endian when the data is put into the ByteBuffer?
Then the getInt() of the Little-endian version will return a right value to you?
当数据放入ByteBuffer时,Java会自动将Big-endian转换为Little-endian吗?
那么 Little-endian 版本的 getInt() 会返回一个正确的值吗?
I guess the answer to above two questions are yes. But when I try to verify my guessing and try to find how the getInt() works in ByteBuffer, I found it is an abstract method. The only subclass of ByteBuffer is the MappedByteBuffer class which didn't implement the abstract getInt(). So where is the implementation of the getInt() method?
我想以上两个问题的答案都是肯定的。但是当我尝试验证我的猜测并尝试找出 getInt() 在 ByteBuffer 中的工作原理时,我发现它是一个抽象方法。ByteBuffer 的唯一子类是 MappedByteBuffer 类,它没有实现抽象的 getInt()。那么getInt()方法的实现在哪里呢?
For the sending, because we are using Little-endian ByteBuffer, we need to convert them into a Big-endian bytes before we put onto the socket.
对于发送,因为我们使用的是 Little-endian ByteBuffer,所以我们需要将它们转换为 Big-endian 字节,然后再放入套接字。
采纳答案by NPE
So where is the implementation of the getInt() method?
那么getInt()方法的实现在哪里呢?
ByteBufferis indeed an abstract class. There are several way in which byte buffers can be created:
ByteBuffer确实是一个抽象类。有几种方法可以创建字节缓冲区:
In my JDK, these create instances of internal classes HeapByteBuffer
and DirectByteBuffer
. Their respective getInt
functions are as follows:
在我的 JDK 中,这些创建了内部类HeapByteBuffer
和DirectByteBuffer
. 它们各自的getInt
作用如下:
// HeapByteBuffer
public int getInt() {
return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
}
public int getInt(int i) {
return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
}
and
和
// DirectByteBuffer
private int getInt(long a) {
if (unaligned) {
int x = unsafe.getInt(a);
return (nativeByteOrder ? x : Bits.swap(x));
}
return Bits.getInt(a, bigEndian);
}
public int getInt() {
return getInt(ix(nextGetIndex((1 << 2))));
}
public int getInt(int i) {
return getInt(ix(checkIndex(i, (1 << 2))));
}
In the above, nativeByteOrder
and bigEndian
are two boolean members indicating respectively -- and somewhat redundantly -- whether the configured byte order: (a) matches the native byte order; (b) is big endian.
在上面,nativeByteOrder
和bigEndian
是两个布尔成员,分别指示 - 并且有点多余 - 配置的字节顺序是否:(a)匹配本机字节顺序; (b) 是大端。
回答by Peter Lawrey
ByteBuffer will automatically use the byte order you specify. (Or Big endian by default)
ByteBuffer 将自动使用您指定的字节顺序。(或默认大端)
ByteBuffer bb =
// to use big endian
bb.order(ByteOrder.BIG_ENDIAN);
// to use little endian
bb.order(ByteOrder.LITTLE_ENDIAN);
// use the natural order of the system.
bb.order(ByteOrder.nativeOrder());
Both direct and heap ByteBuffers will re-order bytes as you specifiy.
直接和堆 ByteBuffers 都将按照您的指定重新排序字节。