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

时间:2013-09-15 13:21:43

标签: java byte

为什么java编译器不允许我将0xff放入byte0xff是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);
        }
}

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

4 个答案:

答案 0 :(得分:50)

Java byte类型是8位有符号整数类型,其值在-128+127范围内。文字0xff代表+255,超出了该范围。

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

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


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

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

在正常情况下,如果没有演员表,您无法将int分配给byte。但是,如果赋值的值是文字,并且文字值在目标类型的范围内,则Java语言允许在不使用转换的情况下分配。文字的值隐含地从int缩小到byte

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

  

“如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。” < / p>

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


<强>后续

  

我看到答案声称0xff255,怎么回事?是不是1111 1111,是什么让0xff-128255或其他任何事情发生?

文字0xff是类型int整数文字。文字int的{​​{1}}值实际上是二进制0xff或十进制+255。相比之下,文字0000 0000 0000 0000 0000 0000 1111 1111具有位模式-1

  

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

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

  

“整数文字的类型为int,如果后缀为ASCII字母longL(ell);否则为{{1}类型}(§4.2.1)。“

答案 1 :(得分:15)

0xff是一个hexadecimal representation的数字。换句话说,这个数字是16的基数。

十六进制中的

f = 15

该值等于

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

这是integer literal(使用4个字节),超出byte的值范围。

您发布的两个示例中的任何一个都不会编译为byte的{​​{1}}值范围。您可以阅读有关基本类型值范围here的信息。

这将有效

-128 to 127

并打印byte a = (byte)0xff; System.out.println(a); ,因为-1转换的字节缩小为255

答案 2 :(得分:4)

0xff为255.虽然这确实适合8位无符号整数,但byte已签名(-128到127)。变窄将移除高位并将8变为8而不考虑符号。

答案 3 :(得分:4)

首先,如果我尝试运行您的代码,那么2.案例也不起作用。您将0xff转换为原始数据类型int(具有32位)并希望将其存储在&#39;字节中。只有8位。 Java也将你的第一个案例视为int,导致同样的问题。

因为java&#39;字节&#39; type是一个8位有符号整数值(从-128到127),以十六进制形式输出/打印字节,你可以使用Integer.toHexString(&#39;原始字节&#39;&amp; 0xFF)其中&# 39; &安培; 0xFF&#39;是一个位掩码,考虑到Integer使用32位int,而byte使用8位。

    byte myByte = (byte)0xff;
    System.out.println(Integer.toHexString(myByte & 0xFF));

输出:

ff