为什么在java中,字节不会0xff?

2022-09-01 10:15:00

为什么java编译器不让我放一个,是8位长,这只是数据类型的大小。

有人可以解释为什么1有效,为什么2不起作用吗?0xffbyte0xffbyte

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);
        }
}

编辑我读到的答案声称0xff是255,怎么会这样?难道不是,是什么使0xff,-128或255或任何与此有关的东西。为什么它不把它当作而不是该字节到1的8位。1111 11111111 1111


答案 1

Java 类型是 8 位有符号整数类型,其值范围为 。文本表示超出该范围的内容。byte-128+1270xff+255

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

在第二个示例中,强制转换正在执行显式缩小转换,该转换删除了整数文本的高阶位...在变量中提供值。(byte)-127byte


实际上,第一个示例的情况比这要复杂一些。请考虑以下情况:

byte a = 1;         // OK
int i = 1;
byte b = i;         // Compilation error
byte c = (byte) i;  // OK

在正常情况下,不能将 a 分配给没有强制转换的 。但是,如果正在分配的值是文本,并且文本值在目标类型的范围内,则 Java 语言允许在没有强制转换的情况下进行赋值。文字的值隐式地从 缩小到 。intbyteintbyte

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

“如果变量的类型是 byte、short 或 char,并且常量表达式的值可以在变量的类型中表示,则可以使用窄基元转换。

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


后续工作

我读到的答案声称是,怎么会这样?难道不是,是什么使,或者任何东西?0xff2551111 11110xff-128255

该文本是 类型的整数文本。文本的值实际上是二进制的,或者是十进制的 +255。相比之下,整数值具有位模式 。0xffintint0xff0000 0000 0000 0000 0000 0000 1111 1111-1281111 1111 1111 1111 1111 1111 1000 0000

为什么它不把它当作而不是该字节到1的8位?1111 1111

因为 是类型为 的整数文本。它不是 8 位文字,因为 Java 中不存在 8 位文字。正如JLS §3.10.1所说:0xffint

“如果整数文本后缀为 ASCII 字母 Ll (ell),则该文本的类型为 long;否则,它是int类型(§4.2.1)。


答案 2

0xff是数字的十六进制表示形式。换句话说,这个数字是以16为基数。

f = 15在十六进制中。

该值等于

15 * 16^1 + 15 * 16^0 = 255

这是一个整数文本(使用 4 个字节),它超过了 的值范围。byte

您发布的两个示例都不会编译,因为两者都不符合 的值范围。您可以在此处阅读有关基元类型值范围的信息byte-128 to 127

这将起作用

byte a = (byte)0xff; 
System.out.println(a);

和 print ,因为 的字节缩小转换是 。-1255-1