在Java中将short转换为byte []

Hug*_*ugh 49 java byte short

如何short在Java中将(2个字节)转换为字节数组,例如

short x = 233;
byte[] ret = new byte[2];

...
Run Code Online (Sandbox Code Playgroud)

它应该是这样的.但不确定.

((0xFF << 8) & x) >> 0;
Run Code Online (Sandbox Code Playgroud)

编辑:

你也可以使用:

java.nio.ByteOrder.nativeOrder();
Run Code Online (Sandbox Code Playgroud)

发现以获取本机位顺序是大还是小.另外,以下代码取自java.io.Bits:

  • byte(array/offset)为布尔值
  • 字节数组到char
  • 字节数组要短
  • 字节数组为int
  • 要浮动的字节数组
  • 字节数组为long
  • 字节数组加倍

反之亦然.

Ale*_*ler 73

ret[0] = (byte)(x & 0xff);
ret[1] = (byte)((x >> 8) & 0xff);
Run Code Online (Sandbox Code Playgroud)

  • 不过那是小端.网络字节顺序是大端:'byte [] arr = new byte [] {(byte)((x >> 8)&0xFF),(byte)(x&0xFF)}; (40认同)
  • 我可以在这里问一下,为什么需要屏蔽,如果将short或int转换为字节只会占用LSB?谢谢 (3认同)
  • 掩蔽是超级的.无论如何,转换为字节都会截断高位,因此将它们屏蔽掉是完全没有意义的. (3认同)
  • 这也可以工作`byte [] arr = new byte [] {(byte)(x >>> 8),(byte)(x&0xFF)}` (2认同)
  • 确实如此——它澄清了意图。当转换为较小的类型时,我通常建议 i) 如果确定不会发生截断,则预先断言,或者 ii) 显式屏蔽。这种策略可以避免大量分析/查找错误工具的误报。 (2认同)

Gil*_*ili 35

一个更清洁,虽然效率低得多的解决方案是:

ByteBuffer buffer = ByteBuffer.allocate(2);
buffer.putShort(value);
return buffer.array();
Run Code Online (Sandbox Code Playgroud)

在将来必须进行更复杂的字节转换时,请记住这一点.ByteBuffers非常强大.

  • @abimelex,是的,这是必要的.最初你在0,1位写入2个字节.如果你没有`buffer.flip()`那么`buffer.array()`将从位置2开始读`byte []``buffer.flip()`将位置设置为0,将限制设置为2,从而最终得到一个从正确位置开始的大小为2的数组.看看Javadoc:http://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html#flip() (2认同)
  • 我们谈论的效率低了多少? (2认同)
  • @Barodapride:根据我自己的测试,我的回答比 http://stackoverflow.com/a/2188682/14731 慢 6.8 倍。也就是说,在大多数情况下,`ByteBuffer` 会“足够好”,而且它肯定更具可读性。意思是,只要分析器说它不是瓶颈,`ByteBuffer` 是否慢一百万倍都没有关系。 (2认同)
  • 更加语义化: `ByteBuffer.allocate(` **`Short.BYTES`** `).putShort(shortValue).array();` (2认同)

Dav*_*vid 14

一种更有效的替代方案:

    // Little Endian
    ret[0] = (byte) x;
    ret[1] = (byte) (x >> 8);

    // Big Endian
    ret[0] = (byte) (x >> 8);
    ret[1] = (byte) x;
Run Code Online (Sandbox Code Playgroud)

  • @bvdb:不需要用 0xFF 进行位掩码,因为一个字节已经是 8 位了。 (2认同)
  • @David 谢谢,仔细检查并确认。:) (2认同)

Hug*_*ugh 7

弄清楚了,它:

public static byte[] toBytes(short s) {
    return new byte[]{(byte)(s & 0x00FF),(byte)((s & 0xFF00)>>8)};
}
Run Code Online (Sandbox Code Playgroud)


Ser*_*aka 6

短字节转换方法在 Kotlin 中对我有用:

 fun toBytes(s: Short): ByteArray {
    return byteArrayOf((s.toInt() and 0x00FF).toByte(), ((s.toInt() and 0xFF00) shr (8)).toByte())
}
Run Code Online (Sandbox Code Playgroud)

  • @Gili 我知道,但这经常是使用 Kotlin 的 Android 开发人员寻找的 (3认同)

bvd*_*vdb 5

这里已经提到了几种方法。但哪一个是最好的呢?以下是一些证明,证明以下 3 种方法对于 a 的所有值都会产生相同的输出short

  // loops through all the values of a Short
  short i = Short.MIN_VALUE;
  do
  {
    // method 1: A SIMPLE SHIFT
    byte a1 = (byte) (i >> 8);
    byte a2 = (byte) i;

    // method 2: AN UNSIGNED SHIFT
    byte b1 = (byte) (i >>> 8);
    byte b2 = (byte) i;

    // method 3: SHIFT AND MASK
    byte c1 = (byte) (i >> 8 & 0xFF);
    byte c2 = (byte) (i & 0xFF);

    if (a1 != b1 || a1 != c1 ||
        a2 != b2 || a2 != c2)
    {
      // this point is never reached !!
    }
  } while (i++ != Short.MAX_VALUE);
Run Code Online (Sandbox Code Playgroud)

结论:少即是多?

byte b1 = (byte) (s >> 8);
byte b2 = (byte) s;
Run Code Online (Sandbox Code Playgroud)

(正如其他答案所提到的,请注意LE/BE)。