java

时间:2015-12-20 13:04:53

标签: java int type-conversion byte type-promotion

我有这段代码:

public class First
{
    public static void main(String[] args)
    {
        byte b=50;
        byte c=b*2;  //Error    
        byte d=50*2;   //d=100
        byte e=(byte)258;   //e=258%256;
        byte f=(byte)128;  //f=128%256;
    }
}
  1. 我知道任何涉及byte的算术表达式都是第一个 升级到int然后执行。所以我期待 d=50*2也报告错误,因为50*2的结果是int 值,我们将它存储在byte中,没有任何显式类型转换。 如果Java隐式执行转换,为什么c=b*2会报告 错误?
  2. 我知道如果我想存储一个值 不在byte变量的范围内,那么我必须明确键入 将其转换为byte,将存储的值为值 模256(字节大小)。因此,为什么byte f=(byte)128会返回 -128?自128 % 256 = 128起,我所期望的是f=128,但它会返回-128。为什么?
  3. 非常感谢。

3 个答案:

答案 0 :(得分:2)

这是因为50*2;将在编译时解析,而b*2;将在运行时解析。因此,在编译时,Java编译器确保50*2;的结果为100.但是在b*2;的情况下,正如您还提到算术运算的结果是int和编译器无法确定结果是否超出byte限制,因此它会抱怨并希望您通过投射或更改类型来确定相关内容。

您可以使用javap -v Test.class进行验证。见下文:

 public static void main(java.lang.String[]);
   flags: ACC_PUBLIC, ACC_STATIC
   Code:
     stack=2, locals=2, args_size=1
        0: bipush        100
        2: istore_1
        3: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        6: iload_1
        7: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
       10: return
     LineNumberTable:
       line 4: 0
       line 5: 3
       line 6: 10

关于你的第二个问题,@ Eran已经解释过使用128和258的位表示,你可以从JLS §5.1.3. Narrowing Primitive Conversion进一步阅读

  

将有符号整数缩小转换为整数类型T.   简单地丢弃除n个最低位之外的所有位,其中n是数字   用于表示类型T的位数。除了可能的丢失   有关数值大小的信息,这可能会导致   结果值的符号与输入符号不同   值。

答案 1 :(得分:1)

关于第二个问题,当你向下转换数字类型时,输入的低位用于初始化输出。

因此,int 128,其二进制表示为0......010000000成为字节10000000(取低8位),即-128

另一方面,2580........01000000010,当你取低8位时,你会得到00000010,即2。

答案 2 :(得分:1)

Java中的自动类型促销

  

除了分配之外,还有另一个地方可能会发生某些类型的转换:即在表达式中。

要了解原因,请考虑以下事项。在表达式中,精度 中间值所需的有时会超过任一操作数的范围。

例如,检查以下表达式:

byte a = 40;
byte b = 50;
byte c = 100;
int d = a * b / c;

中间项a * b的结果很容易超出其任一字节操作数的范围。为了处理此类问题,Java在评估表达式时会自动将每个byteshortchar操作数提升为int

这意味着子表达式a*b使用整数而不是字节来执行。因此,2,000,即中间表达式50 * 40的结果是合法的,即使a和b都被指定为类型字节。

  

与自动促销一样有用,它们会导致混乱的编译时间   错误。

例如,这个看似正确的代码会导致问题:

byte b = 50;
b = b * 2; // Error! Cannot assign an int to a byte!

代码尝试将50 * 2(完全有效的byte值)存储回byte变量。但是,由于在计算表达式时操作数会自动提升为int,因此结果也会提升为int。因此,表达式的结果现在是int类型,如果不使用byte,则无法将其分配给cast

即使在这种特殊情况下,所分配的值仍然适合目标类型,也是如此。 如果您了解溢出的后果,则应使用显式转换,例如

byte b = 50;
b = (byte)(b * 2);

产生正确的值100。