Java:在原始数组上使用类型双关?
我需要能够在字节数组与其他原始类型数组之间进行转换,但我需要 类型双关。 不进行强制转换的原始副本的正确术语?
我认为可以执行以下操作:
// idea: byte[12] -> int[3], and int[3] -> byte[12]
int[] ints;
ByteBuffer bb = ByteBuffer.wrap(
new byte[]{ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3 });
IntBuffer ib = bb.asIntBuffer();
ints = ib.array(); // java.lang.UnsupportedOperationException
ints = ib.duplicate().array(); // java.lang.UnsupportedOperationException
不幸的是,似乎 bb.asIntBuffer()
是不是.array() 注定会失败的原因。
我浏览了 JDK 的源代码,发现很少有类,它们被所有这些缓冲区类使用,并且会做我需要的事情,但是是内部的(例如类Unsafe
)。
虽然我认为我的目标可以通过将字节缓冲区包装在一些 ObjectInputStream
中并通过 .readInt()
读取原始值来实现,但我认为这将是一个混乱且混乱的过程。缓慢的解决方法。
那么,是否有任何其他可能的解决方案而不进行神奇的原始类型算术(移位、检查字节序……)?
注意:我需要两个方向:byte[12] -> int[3] 和 int[3] ->字节[12]
I need to be able to convert byte arrays to/from other primitive type arrays, but instead of casting, I need type punning. Correct term for raw copy without casting?
I thought it would be possible to do the following:
// idea: byte[12] -> int[3], and int[3] -> byte[12]
int[] ints;
ByteBuffer bb = ByteBuffer.wrap(
new byte[]{ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3 });
IntBuffer ib = bb.asIntBuffer();
ints = ib.array(); // java.lang.UnsupportedOperationException
ints = ib.duplicate().array(); // java.lang.UnsupportedOperationException
Unfortunately, it seems that bb.asIntBuffer()
is not creating a new IntBuffer by copying the content "bitwise" or "raw", but creates a new "view" on existing ByteBuffer. That's why .array()
is intended to fail.
I browsed around in JDK's sources, and found few classes, which are used by all these buffer classes and would do the stuff I need, but are internal (such as the class Unsafe
).
While I think that my goal could be achieved by wrapping the byte buffer in some ObjectInputStream
and read the primitive values by .readInt()
, I think it would be a messy and slow workaround.
So, are there any other solutions possible without doing magical primitive type arithmetics (shifting, checking endians, ...)?
NOTE: I need both directions: byte[12] -> int[3], and int[3] -> byte[12]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 javadoc,array() [1] 返回缓冲区的支持数组,该数组是您通过调用 wrap() [2] 指定的数组。
因此,您必须创建一个具有所需类型的新数组。但算术仍然可以通过 Buffer 类进行处理。
倒退需要你自己稍微计算一下。
请参阅:
[1] http: //java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html#array%28%29
[2] http://java.sun.com/javase/6/docs/api/java /nio/ByteBuffer.html#wrap%28byte[]%29
According to the javadoc, array() [1] returns the buffer's backing array which is the array you specify with the call to wrap() [2].
Hence, you must create a new array with the desired type. But the arithmetics can still be handled via the Buffer classes.
Backwards requires a little bit of calculation by yourself.
See:
[1] http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html#array%28%29
[2] http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html#wrap%28byte[]%29
非常感谢 wierob 提供的转换 byte[]->int[] 的代码!
我尝试了一下,让相反的方向工作。
1) API
2) 测试用例
3) 输出
Many thanks to wierob for his code for converting byte[]->int[] !
I played around a bit to get the opposite direction working.
1) API
2) Test case
3) Output