java - 使用字节掩码防止符号扩展

标签 java networking bytearray endianness

我一直在阅读《Java 中的 TCP/IP 套接字》,第 2 版。我希望能更清楚地了解一些事情,但由于这本书的网站没有论坛或其他任何东西,我想我应该在这里问一下。 在几个地方,本书使用字节掩码来避免符号扩展。这是一个例子:

private final static int BYTEMASK = 0xFF; //8 bits

public static long decodeIntBigEndian(byte[] val, int offset, int size) {
    long rtn = 0;
    for(int i = 0; i < size; i++) {
        rtn = (rtn << Byte.SIZE) | ((long) val[offset + i] & BYTEMASK);
    }
    return rtn;
}

所以这是我对发生的事情的猜测。如果我是对的,请告诉我。 BYTEMASK二进制应该看起来像00000000 00000000 00000000 11111111 . 为了简单起见,我们只说 val字节数组只包含 1 个 short,所以偏移量为 0。所以让我们将字节数组设置为 val[0] = 11111111 , val[1] = 00001111 .在 i = 0 , rtn都是0所以rtn << Byte.SIZE只是保持值(value)相同。然后是(long)val[0]由于符号扩展,使其成为 8 个字节,全 1。但是当你使用 & BYTEMASK ,它将所有那些额外的 1 设置为 0,最后一个字节全部为 1。然后你得到rtn | val[0]基本上翻转 rtn 的最后一个字节中的任何 1 .对于 i = 1 , (rtn << Byte.SIZE)将最低有效字节推到前面并保留所有 0。然后 (long)val[1]用全零加上 00001111 做多对于我们想要的最低有效字节。所以使用 & BYTEMASK不会改变它。然后当rtn | val[1]使用,它翻转rtn的最低有效字节为全 1。现在的最终返回值是 rtn = 00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111111 . 所以,我希望这不会太长,而且是可以理解的。我只想知道我思考这个问题的方式是否正确,而不是完全搞砸了逻辑。另外,让我感到困惑的一件事是 BYTEMASK0xFF .在二进制中,这将是 11111111 11111111 ,所以如果它被隐式转换为 int,它实际上不是 11111111 11111111 11111111 11111111 吗?由于符号扩展?如果是这样的话,那么 BYTEMASK 对我来说就没有意义了。甚至会工作。感谢您的阅读。

最佳答案

除了最后一点,一切都是对的:

0xFF 已经是一个 int (0x000000FF),因此它不会被符号扩展。一般来说,integer number literals在 Java 中是 int,除非它们以 Ll 结尾,然后它们是 long

关于java - 使用字节掩码防止符号扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10473324/

相关文章:

java - 将字符串转换为整数(对象)数组 Java

c++ - 在 Windows 和 Linux 之间通过 C++ 套接字发送 float 组

model-view-controller - Haskell 是否有任何 MVC Web 框架?

java - 在 J2ME 中如何从另一个类对象中获取一个 byte[] 对象?

java - 如何以编程方式为 mysql jdbc 驱动程序设置 rewriteBatchedStatements?

java - 在 Java 中,如何从资源构造文件?

c# & java 套接字和字节数据读取开销

java - RCP - 应用程序没有 Activity 窗口

docker - 如何为不同的容器访问 docker 内的公共(public) IP