2010-05-03 93 views
2

有人可以解释为什么下面这段代码无法编译。错误是:“Possible loss of precision.”:编译错误:铸造

byte a = 50; 
byte b = 40; 
byte sum = (byte)a + b; 
System.out.println(sum); 

谢谢。

回答

1

您通过识别铸造是必需的,但不幸的是你没有把它应用到合适的表情,由于运营商的优先做得对。

考虑下面的代码片段:

static void f(char ch) { 
    System.out.println("f(char)"); 
} 
static void f(int i) { 
    System.out.println("f(int)"); 
} 
public static void main(String[] args) { 
    char ch = 'X'; 
    f((char) ch + 1 ); // prints "f(int)" 
    f((char) (ch + 1)); // prints "f(char)" 
} 

演员具有更高的优先级比加,这就是为什么片断输出它做什么。也就是说,第一个电话相当于f(((char) ch) + 1);。添加的结果是int,这就是调用f(int)重载的原因。

这里的教训是,你应该总是使用括号,除非你做了一个非常简单的演员。通常,考虑使用括号来明确评估顺序,即使它们不是必需的。它们导致更好,更易读的代码。

1

使用“int”算术添加字节;因此结果是int,并且必须从int转换回byte,这会导致截断的可能性。

3

因为两个字节变量的操作数为+,所以它们被隐式提升为int。这被称为数字促销。因为int大于字节,并且a + b的结果产生int,所以转换为字节可能会删除一些位,因为int大于字节。因此,

文件隐数值提升“的精度损失”:

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983

文件的类型大小:

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html

+0

从我的角度来看,这有点愚蠢。编程语言不应该关心这种错误。但我现在明白这个问题。谢谢。 – 2010-05-03 07:48:54

+0

我对Java编译器知之甚少,但在大多数只是警告的C编译器中。考虑自己是幸运的;) – 2010-05-03 07:50:34

4

请注意,铸铁具有更高的优先级比+运营商。您的代码做到这一点:

byte a = 50; 
byte b = 40; 
byte sum = ((byte)a) + b; 
System.out.println(sum); 

演员是多余的,因为a已经是一个byte。你大概意思是:

byte a = 50; 
byte b = 40; 
byte sum = (byte) (a + b); 
System.out.println(sum); 
+1

+1:这是关键部分;演员没有被应用于提问者可能认为是的东西。 – 2010-05-03 08:17:58