4

我一直在阅读《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 个短字节,因此偏移量为 0。所以让我们将字节数组设置为val[0] = 11111111, val[1] = 00001111。在i = 0,rtn都是 0,所以rtn << Byte.SIZE保持值不变。然后(long)val[0]由于符号扩展,它变成了 8 个字节,全为 1。但是当您使用 时& BYTEMASK,它会将所有额外的 1 设置为 0,将最后一个字节全部保留为 1。然后你会得到rtn | val[0]它基本上会翻转 . 的最后一个字节中的任何 1 rtn。对于i = 1,(rtn << Byte.SIZE)将最不重要的字节推到上面,并将所有 0 留在原处。然后(long)val[1]用全零加长00001111对于我们想要的最低有效字节。所以使用& BYTEMASK不会改变它。然后在使用时,它将' 的最低有效字节rtn | val[1]翻转为全 1。rtn最终返回值为 now rtn = 00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111111。所以,我希望这不会太长,这是可以理解的。我只是想知道我的思考方式是否正确,而不仅仅是完全不合逻辑。另外,让我感到困惑的一件事是BYTEMASKis 0xFF。在二进制中,这将是11111111 11111111,所以如果它被隐式转换为 int,它实际上不是11111111 11111111 11111111 11111111由于符号扩展吗?如果是这样的话,那么对我来说如何工作就没有意义了BYTEMASK。感谢您的阅读。

4

1 回答 1

6

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

0xFF已经是int( 0x000000FF),因此不会进行符号扩展。一般来说,Java 中的整数字面量是 s,除非它们以orint结尾,然后它们就是s。Lllong

于 2012-05-06T19:07:35.783 回答