0

我只是在玩类型转换。这是代码:

class Typecasting {
    public static void main(String[] args) {
       byte b = 3;
       byte c = b++;   // no error
       byte d = b + 1; // error
       byte e = b + b; // error
    }
}

为什么第一行没有错误,第二行没有错误?当我这样做的时候

f = b + 2;

我知道这b是自动转换为int类型的,因此f必须是int类型,但是当我这样做时

e = b + b;

它们都是byte类型,它们的结果也在 a 的范围内byte,那么为什么不能ebyte数据类型呢?是由于+二元运算符吗?

4

6 回答 6

3

为什么第一行没有错误,而第二行没有错误?

因为这就是语言的定义方式。没有byte + byte运算符,这就是第三行失败的原因——两个操作数都被自动提升为int。从JLS 的第 15.18.2 节

二进制 + 运算符在应用于两个数字类型的操作数时执行加法,产生操作数的和。

...

对操作数执行二进制数字提升(第 5.6.2 节)。

现在,在这种情况下,二进制数字提升总是以 、 或 ... 的int值结束。所以操作是将两个值相加,结果是一个.longfloatdoubleintintint

然而,对于b++,类型仍然是byte。这是一个后缀增量表达式(第 15.14.2 节)

后缀增量表达式的类型是变量的类型。

在相关的说明中,这没关系:

b += 3;

这是一个复合赋值(第 15.26.2 节)

形式的复合赋值表达式E1 op= E2等价于E1 = (T) ((E1) op (E2)),其中T是 的类型E1,除了E1只计算一次。

注意铸造部分,这就是它起作用的原因。

于 2013-07-05T05:50:33.707 回答
0

+(byte, byte)int根据语言规则返回一个。

规范的相关部分是§5.6.2:

当运算符将二进制数字提升应用于一对操作数时,每个操作数都必须表示一个可转换为数字类型的值,以下规则按顺序应用,使用扩展转换(第 5.1.2 节)在必要时转换操作数:

  • 如果任何操作数是引用类型,则执行拆箱转换(第 5.1.8 节)。然后:
  • 如果任一操作数是类型double,则将另一个转换为double
  • 否则,如果任一操作数的类型为float,则将另一个转换为float
  • 否则,如果任一操作数的类型为long,则将另一个转换为long
  • 否则,两个操作数都转换为 typeint

而对于++,结果的类型是操作数的类型。来自 JLS,§15.14.2:

后缀增量表达式的类型是变量的类型。

因此,对于b++,结果a byte,因此可分配给c

于 2013-07-05T05:51:06.037 回答
0
byte c = b++; //No error;First Line

这符合JLS 15.14.2

后缀增量表达式的类型是变量的类型。后缀增量表达式的结果不是一个变量,而是一个值。

byte d = b+1;   //error;Second Line
byte e = b+b;    //error;Third line

这符合JLS 15.18.2

二进制 + 运算符在应用于两个数字类型的操作数时执行加法,产生操作数的和。

数值操作数上的加法表达式的类型是其操作数的提升类型。

如果此提升的类型是 int 或 long,则执行整数运算。

阅读JLS 5.6.2中的类型提升

加宽原语转换(第 5.1.2 节)适用于转换以下规则指定的一个或两个操作数:

如果任一操作数是 double 类型,则另一个操作数将转换为 double。

否则,如果任一操作数的类型为浮点型,则另一个将转换为浮点型。

否则,如果任一操作数是 long 类型,则另一个将转换为 long。

否则,两个操作数都转换为 int 类型。

于 2013-07-05T05:57:24.190 回答
0
byte d = b+1; 

在这里,您将 int value(b+1) 分配给byted。当您将 int 值添加到字节值时,它变为 int 值。

于 2013-07-05T05:55:02.540 回答
0

在第一行 ++operator 总是返回操作数类型的结果..所以它没有给出错误

在第二行,这里的 1 是一个整数类型,因为默认情况下所有整数类型文字都是 int

在第三行 +(byte,byte) 返回整数类型,为什么它会强制您将其类型转换为 int。

--> 在第三行中,字节类型总是有溢出的可能性。 *如果你的字节类型被定义为常量,那么它不会强迫你进行类型转换,因为它总是在范围内。

于 2013-07-05T06:00:00.810 回答
-1

当 Java 执行求和时,它首先将两个操作数“转换”为intlong(取决于操作数),结果将是一个整数,它将尝试分配给您的 byte 类型的变量,因为它“实现”了结果不适合一个字节,然后它会“抱怨”,你甚至无法编译它。

于 2013-07-05T05:50:52.803 回答