为什么byte不会在java中占用0xff?

vik*_*cks 27 java byte

为什么java编译器不让我0xff加入byte,0xff是8位长,这只是byte数据类型的大小.

有人可以解释为什么1有效,为什么有2无效?

class a
{
        public static void main(String[] args)
        {
                // 1 :: results in error
                byte a = 0xff;          
                System.out.printf("%x\n",a);

                //2 :: works fine
                byte a = (int)0xff              
                System.out.printf("%x\n",a);
        }
}
Run Code Online (Sandbox Code Playgroud)

编辑我读了答案声称0xff是255,怎么回事?是不是1111 1111,什么使0xff,-128或255或任何事情.为什么不将它视为1111 1111而不是将该字节的8位视为1.

Ste*_*n C 52

在Java byte类型是一个8位有符号整数类型与在范围内的值-128+127.文字0xff表示+255超出该范围的文字.

在第一个示例中,您尝试将超出范围的值分配给a byte.这是一个编译错误.

在第二个例子中,(byte)投正在执行一个明确的收缩转换,即消除了整数文字的高位...给你的价值-127在你的byte变量.


事实上,第一个例子的情况比这复杂一点.考虑一下:

byte a = 1;         // OK
int i = 1;
byte b = i;         // Compilation error
byte c = (byte) i;  // OK
Run Code Online (Sandbox Code Playgroud)

在正常情况下,您无法在没有强制转换的情况下分配int给a byte.但是,如果赋值的值是文字,并且文字值在目标类型的范围内,则Java语言允许在没有强制转换的情况下进行赋值.文字的价值隐含地缩小intbyte.

JLS§5.2中描述了这一点,它定义了可以在赋值中执行的转换:

"如果变量的类型是byte,short或char,则可以使用缩小的原始转换,并且常量表达式的值可以在变量的类型中表示."

正如您所看到的,这不仅适用于文字.它适用于所有(编译时)常量表达式!


跟进

我读到的答案声称0xff255,怎么会这样?是不是1111 1111,是什么造成的0xff,-128或者255说是什么?

文字0xff是类型的整数文字int.int文字的值0xff实际上0000 0000 0000 0000 0000 0000 1111 1111是二进制或+255(十进制).相比之下,文字-128具有位模式1111 1111 1111 1111 1111 1111 1000 0000.

为什么不将它作为1111 1111而不是将该字节的8位视为1?

因为0xff是一个带有类型的整数文字int.它不是8位字面值,因为Java中不存在8位字面值.正如JLS§3.10.1所说:

"如果整数文字long后缀为ASCII字母Ll(ell),则为整数文字;否则为类型int(§4.2.1)."


Sot*_*lis 15

0xff是数字的十六进制表示.换句话说,数字是16.

f = 15 十六进制

该值等于

15 * 16^1 + 15 * 16^0 = 255
Run Code Online (Sandbox Code Playgroud)

这是一个整数文字(使用4个字节),超出了byte值的范围.

你发布的两个例子都没有编译,因为它们都不符合byte的值范围-128 to 127.你可以阅读有关原始类型取值范围在这里.

这会奏效

byte a = (byte)0xff; 
System.out.println(a);
Run Code Online (Sandbox Code Playgroud)

和打印-1,因为一个字节收缩转换255-1.